ask-monarch 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. ask_monarch-0.1.0/PKG-INFO +867 -0
  2. ask_monarch-0.1.0/README.md +860 -0
  3. ask_monarch-0.1.0/ask_monarch.egg-info/PKG-INFO +867 -0
  4. ask_monarch-0.1.0/ask_monarch.egg-info/SOURCES.txt +47 -0
  5. ask_monarch-0.1.0/ask_monarch.egg-info/dependency_links.txt +1 -0
  6. ask_monarch-0.1.0/ask_monarch.egg-info/entry_points.txt +2 -0
  7. ask_monarch-0.1.0/ask_monarch.egg-info/top_level.txt +1 -0
  8. ask_monarch-0.1.0/ask_monarch_cli/__init__.py +1 -0
  9. ask_monarch-0.1.0/ask_monarch_cli/agent_setup.py +112 -0
  10. ask_monarch-0.1.0/ask_monarch_cli/answer_shape_contracts.py +940 -0
  11. ask_monarch-0.1.0/ask_monarch_cli/cli.py +2527 -0
  12. ask_monarch-0.1.0/ask_monarch_cli/routing_decision.py +10501 -0
  13. ask_monarch-0.1.0/ask_monarch_cli/skills/askmonarch/SKILL.md +516 -0
  14. ask_monarch-0.1.0/ask_monarch_cli/skills/braintrust/SKILL.md +58 -0
  15. ask_monarch-0.1.0/ask_monarch_cli/skills/correction/SKILL.md +77 -0
  16. ask_monarch-0.1.0/ask_monarch_cli/skills/monarch-source/SKILL.md +241 -0
  17. ask_monarch-0.1.0/pyproject.toml +20 -0
  18. ask_monarch-0.1.0/setup.cfg +4 -0
  19. ask_monarch-0.1.0/tests/test_adapter_modifiers.py +355 -0
  20. ask_monarch-0.1.0/tests/test_answer_quality.py +236 -0
  21. ask_monarch-0.1.0/tests/test_answer_shape_contracts.py +796 -0
  22. ask_monarch-0.1.0/tests/test_ask_monarch_cli.py +1595 -0
  23. ask_monarch-0.1.0/tests/test_ask_monarch_setup.py +230 -0
  24. ask_monarch-0.1.0/tests/test_assay_media_links.py +272 -0
  25. ask_monarch-0.1.0/tests/test_assay_metric_overlay.py +296 -0
  26. ask_monarch-0.1.0/tests/test_braintrust_tracing.py +124 -0
  27. ask_monarch-0.1.0/tests/test_bucket_dart_query.py +87 -0
  28. ask_monarch-0.1.0/tests/test_cross_source_pressure.py +144 -0
  29. ask_monarch-0.1.0/tests/test_evidence_shapes.py +87 -0
  30. ask_monarch-0.1.0/tests/test_golden_route_soak.py +394 -0
  31. ask_monarch-0.1.0/tests/test_hard_probe_generator.py +146 -0
  32. ask_monarch-0.1.0/tests/test_install_script.py +241 -0
  33. ask_monarch-0.1.0/tests/test_monarch_chemistry_analysis.py +140 -0
  34. ask_monarch-0.1.0/tests/test_onboarding_codes.py +53 -0
  35. ask_monarch-0.1.0/tests/test_personal_mail.py +133 -0
  36. ask_monarch-0.1.0/tests/test_prime_simple_setup.py +141 -0
  37. ask_monarch-0.1.0/tests/test_rd_goal_verifier.py +37 -0
  38. ask_monarch-0.1.0/tests/test_rd_probe_eval.py +47 -0
  39. ask_monarch-0.1.0/tests/test_refresh_source_index.py +447 -0
  40. ask_monarch-0.1.0/tests/test_route_triage_ledger.py +62 -0
  41. ask_monarch-0.1.0/tests/test_routing_centrality_guard.py +114 -0
  42. ask_monarch-0.1.0/tests/test_routing_decision.py +2755 -0
  43. ask_monarch-0.1.0/tests/test_routing_decision_eval.py +139 -0
  44. ask_monarch-0.1.0/tests/test_semantic_router_playground.py +71 -0
  45. ask_monarch-0.1.0/tests/test_serve_http_onboarding.py +148 -0
  46. ask_monarch-0.1.0/tests/test_serving_tables.py +292 -0
  47. ask_monarch-0.1.0/tests/test_teammate_onboarding_simulator.py +606 -0
  48. ask_monarch-0.1.0/tests/test_teams_recap_fetcher.py +31 -0
  49. ask_monarch-0.1.0/tests/test_traced_query.py +654 -0
@@ -0,0 +1,867 @@
1
+ Metadata-Version: 2.4
2
+ Name: ask-monarch
3
+ Version: 0.1.0
4
+ Summary: Thin CLI for the hosted Ask Monarch source plane
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+
8
+ # Ask Monarch
9
+
10
+ ## Teammate Setup
11
+
12
+ Install Ask Monarch for a teammate with one command:
13
+
14
+ ```bash
15
+ uvx ask-monarch setup --code MNR-BUSE-U8E8
16
+ ```
17
+
18
+ The code is stable until Josh or an admin rotates it. This command installs or
19
+ refreshes the persistent CLI, exchanges the setup code, configures Codex and
20
+ Claude Code, runs doctor, runs the canonical verification query, and reports
21
+ the source id.
22
+
23
+ Ask Monarch is the conversational front door to its memory and capabilities.
24
+
25
+ A teammate should be able to ask Monarch what it knows, inspect the evidence, challenge the answer, and improve the memory as new artifacts appear.
26
+
27
+ Under the hood, Ask Monarch does not ask the live bucket or a loose pile of
28
+ files every time. It follows the source contract:
29
+
30
+ ```text
31
+ map the source -> access it -> enumerate it -> parse it into atomic units -> verify receipts -> make it queryable
32
+ ```
33
+
34
+ Once a source passes that gate, Ask Monarch answers from the parsed indexes with provenance. That is what makes answers fast, repeatable, and inspectable.
35
+
36
+ Read [ASKMONARCH-SPEC.md](ASKMONARCH-SPEC.md) for the deeper product contract and future direction.
37
+
38
+ ## Architecture
39
+
40
+ Ask Monarch is artifact-first: raw company artifacts flow through the
41
+ `monarch-source` contract into a searchable store, then the `ask-monarch` CLI is
42
+ the supported ask path.
43
+
44
+ ![Ask Monarch architecture](docs/ask-monarch-architecture.png)
45
+
46
+ Runtime: the GitHub repo `manintheandes/ask-monarch` is deployed to the
47
+ `ask-monarch-server` VM; the CLI runs on the user or agent machine and calls the
48
+ hosted API on that VM.
49
+
50
+ ## Visual Explainers
51
+
52
+ Ask Monarch's architecture and assay explainers are repo-owned visual assets.
53
+ Manim scenes live in [visuals/manim](visuals/manim). Remotion demo videos live
54
+ in [videos](videos). Both are scoped away from the hosted API and CLI runtime.
55
+
56
+ ```bash
57
+ cd visuals/manim
58
+ uv run manim -pql scenes.py AskMonarchArchitecture
59
+ ```
60
+
61
+ For assay visuals, start with Manim's plotting examples and map source-backed
62
+ rows onto axes, curves, markers, guide lines, and highlighted regions. See
63
+ [visuals/manim/README.md](visuals/manim/README.md).
64
+
65
+ For the current visual evidence loop, run the root verifier:
66
+
67
+ ```bash
68
+ python3 scripts/verify_visual_evidence.py
69
+ ```
70
+
71
+ That checks the source-action hook, overlay resolver, assay-overlay CLI dry-run,
72
+ Manim brand palette, reusable Manim assay templates, and a smoke still render.
73
+
74
+ For Remotion video work, use the repo-owned brand tokens in
75
+ [videos/src/brand.ts](videos/src/brand.ts) and validate with
76
+ `npm run validate:brand` from the `videos` folder.
77
+
78
+ ## Current State
79
+
80
+ Ask Monarch currently has ten verified source lanes. For the fuller
81
+ human-readable source list, see [docs/source-lanes.md](docs/source-lanes.md).
82
+
83
+ | Source lane | What it covers | Status |
84
+ | --- | --- | --- |
85
+ | `bucket` | `gs://monarch-videos-new`, including experiment outputs, CSV rows, spreadsheets, images, videos, PDFs, model metadata, and structured sidecars | Parsed and queryable |
86
+ | `presentations` | 37 Monarch update decks from the `Storyboards_Presentations` Google Drive folder, scoped to January 1, 2026 onward | Parsed and queryable |
87
+ | `company_profile` | Monarch mission, problem, status quo, approach, headquarters, organisms, and crop-testing context | Parsed and queryable |
88
+ | `people_directory` | Monarch employees, advisors, and partnership facts | Parsed and queryable |
89
+ | `company_context` | Company context from `Monarch_for_askmonarch.pdf`, parsed into PDF pages, text blocks, and embedded-image references | Parsed and queryable |
90
+ | `teams_recaps` | Recurring `Monarch R&D`, `Monarch Weekly`, and `Monarch Team Sync` Teams meeting transcripts, refreshed daily after midnight | Parsed and queryable |
91
+ | `scientific_refs` | Scoped scientific reference library, including chemical ecology, receptor/pathway, modeling, assay-prototype, scalability, EPA registration-support, and Teams-discussed journal-article material | Parsed and queryable |
92
+ | `milestones_doc` | `monarch_milestones` Google Doc, scoped to one fetched revision and parsed into paragraph units | Parsed and queryable |
93
+ | `compound_inventory` | Monarch compound / chemical inventory workbook from the user-provided `Updated Chemical Inventory.xlsx` attachment | Parsed and queryable |
94
+ | `chemistry_analysis` | `gs://monarch-chemistry-analysis`, including chemical activity registry rows, docking result rows, JSON score sidecars, protein-structure metadata, model metadata, images, scripts, and text sidecars | Parsed and queryable |
95
+
96
+ Current presentation receipt:
97
+
98
+ - 37 decks
99
+ - 557 slides
100
+ - 1,087 slide text or notes units
101
+ - 673 media/chart/link references
102
+ - 0 explicit gaps
103
+
104
+ The bucket receipt currently proves all live bucket objects are parsed and that
105
+ CSV rows are materialized atomically in SQLite. The large CSV-row count is not an
106
+ animal count; it is source-unit count from processed frame/result files.
107
+
108
+ Current Teams recap receipt:
109
+
110
+ - 24 meeting instances across R&D, Weekly, and Team Sync through May 12, 2026
111
+ - 24 matching transcript files
112
+ - 12,595 speaker/timestamp/utterance units
113
+ - 0 explicit gaps
114
+
115
+ Current company profile receipt:
116
+
117
+ - 7 company profile units
118
+ - 0 explicit gaps
119
+
120
+ Current people directory receipt:
121
+
122
+ - 15 people, advisor, and partnership units
123
+ - 0 explicit gaps
124
+
125
+ Current company context receipt:
126
+
127
+ - 22 PDF pages
128
+ - 89 text blocks
129
+ - 59 embedded-image references
130
+ - 171 total atomic units
131
+ - 0 explicit gaps
132
+
133
+ Current milestones doc receipt:
134
+
135
+ - 1 Google Doc revision
136
+ - 30 paragraph units
137
+ - 0 tables
138
+ - 0 comments
139
+ - 0 explicit gaps
140
+
141
+ Current compound / chemical inventory receipt:
142
+
143
+ - 8 workbook sheets
144
+ - 1,806 rows with values
145
+ - 9,280 non-empty cell units
146
+ - 0 explicit gaps
147
+ - Original SharePoint link access still failed for the current connector identity; the parsed source is the attached workbook copy.
148
+
149
+ Current chemistry analysis receipt:
150
+
151
+ - 11,302 bucket objects
152
+ - 550,576 CSV row units
153
+ - 30,412 JSON units
154
+ - 99,206 text line units
155
+ - 3,637 protein-structure metadata units
156
+ - 0 explicit gaps
157
+
158
+ Current Braintrust receipt:
159
+
160
+ - Project: `Andes / ask-monarch`
161
+ - Project id: `28216333-66fb-42a6-923b-622bda7a2fcc`
162
+ - Query responses include `trace_id`, `trace_span_id`, `trace_project`, `trace_project_id`, and `trace_url` when `BRAINTRUST_API_KEY` is configured.
163
+ - Query traces include spans for `trace.user_question`, `trace.tool_call.1.ask_monarch_source_query`, `trace.selected_evidence`, `trace.source_receipts`, and `trace.final_answer`.
164
+
165
+ ## How To Ask
166
+
167
+ In any capable coding or research agent, use the repo-owned Ask Monarch skill:
168
+
169
+ ```text
170
+ what is the most effective compound against mosquitoes [$askmonarch](/Users/josh/.codex/skills/askmonarch/SKILL.md)
171
+ ```
172
+
173
+ The user should not need to know which source, database, table, bucket, or deck
174
+ contains the answer. `$askmonarch` means: use the skill's routing rules, call
175
+ the `ask-monarch` CLI for evidence, answer from the returned rows, and say
176
+ clearly when the memory does not yet contain enough evidence.
177
+
178
+ Personal mailbox access is a live overlay, not shared company memory. A mapped
179
+ Josh-only Ask Monarch token can access the shared Monarch source plane and the
180
+ mapped `josh@monarchcrops.com` mailbox through Microsoft Graph; the shared/team
181
+ token cannot access personal mail, and personal mail is not indexed into shared
182
+ SQLite.
183
+
184
+ For direct shell use, the remote CLI calls the hosted Ask Monarch service:
185
+
186
+ ```bash
187
+ ask-monarch health
188
+ ask-monarch summary
189
+ ask-monarch query "what are the most effective repellents?"
190
+ ask-monarch query "list the experiments from last week" --limit 10
191
+ ask-monarch query "what did today's presentation cover?" --source presentations --limit 8
192
+ ask-monarch presentation --latest --open
193
+ ask-monarch presentation --date 2026-01-02 --open
194
+ ask-monarch query "what did the latest R&D meeting cover?" --source teams_recaps --limit 8
195
+ ask-monarch query "what does Monarch do?" --source company_profile --limit 8
196
+ ask-monarch query "who works at Monarch?" --limit 50
197
+ ask-monarch query "what does the company context say about residues?" --source company_context --limit 8
198
+ ask-monarch search "2pp mosquito" --limit 5
199
+ ask-monarch search damage --source presentations --limit 5
200
+ ask-monarch search "spatial repellents" --source teams_recaps --limit 5
201
+ ask-monarch search "acetone" --source compound_inventory --limit 5
202
+ ask-monarch company-profile-search mission --limit 5
203
+ ask-monarch people-search advisor --kind advisors --limit 10
204
+ ask-monarch company-context-search glossary --limit 5
205
+ ask-monarch query "62 chemicals" --source milestones_doc --limit 5
206
+ ask-monarch milestones-search "62 chemicals" --limit 5
207
+ ask-monarch compound-inventory-search acetone --limit 5
208
+ ask-monarch search DEET --source chemistry_analysis --limit 5
209
+ ask-monarch sql "SELECT COUNT(*) AS rows FROM csv_rows" --source chemistry_analysis
210
+ ask-monarch csv-search IR3535 --name-like combined_results.csv --limit 5
211
+ ask-monarch sql "SELECT COUNT(*) AS slides FROM slide_units" --source presentations
212
+ ask-monarch --open-trace query "what does Monarch do?" --source company_profile --limit 5
213
+ ask-monarch trace-url TRACE_ID
214
+ ask-monarch personal-mail-status
215
+ ask-monarch personal-mail-search "mosquito field trial" --days 30 --limit 10
216
+ ask-monarch personal-mail-read GRAPH_MESSAGE_ID
217
+ ask-monarch personal-mail-draft --to person@example.com --subject "Subject" --body "Body"
218
+ ask-monarch personal-mail-reply-draft GRAPH_MESSAGE_ID --body "Reply body"
219
+ ask-monarch personal-mail-send-draft GRAPH_DRAFT_ID
220
+ ```
221
+
222
+ The CLI returns JSON so Codex, Claude Code, shell scripts, and dashboards can
223
+ consume the same source evidence reliably.
224
+
225
+ ## How Corrections Improve Ask Monarch
226
+
227
+ When Ask Monarch gives a weak answer, the fix should become part of the system,
228
+ not just part of one chat. There are three places to make that correction.
229
+
230
+ For source-question regressions, run the live drill:
231
+
232
+ ```bash
233
+ python3 scripts/run_askmonarch_regression.py
234
+ ```
235
+
236
+ The drill replays known tricky questions against the hosted source service and
237
+ checks both the returned source values and the `$askmonarch` skill rules that
238
+ should route future agents correctly. When a case fails, reproduce it manually,
239
+ patch the skill/source/parser/CLI layer that caused the miss, then add or
240
+ tighten the case before rerunning the drill.
241
+
242
+ Latency counts too. The drill prints wall-clock time per case, summarizes the
243
+ slowest case, and fails any case over the default per-case budget of 10 seconds.
244
+ Use `--default-max-seconds` to tune the budget for a run, or set `max_seconds`
245
+ on a case that deserves a tighter or looser threshold.
246
+
247
+ When intentionally failure-mining, use plausible teammate questions, not
248
+ impossible trivia. Count a failure when the hosted source path returns no
249
+ usable evidence, the route is ambiguous, units cannot be verified, or the answer
250
+ would require inventing a linkage. Each useful failure should leave behind a
251
+ durable rule, a regression case, or a named source/tooling gap.
252
+
253
+ For answer-quality regressions, run the live answer contract gate:
254
+
255
+ ```bash
256
+ python3 scripts/verify_askmonarch_answer_quality.py
257
+ ```
258
+
259
+ For a clean pass/fail check that does not rewrite the committed ledger outputs:
260
+
261
+ ```bash
262
+ python3 scripts/verify_askmonarch_answer_quality.py --check-only
263
+ ```
264
+
265
+ That gate checks that composed answers include the requested factual claims,
266
+ that evidence rows have citations, that broad questions cite multiple source
267
+ lanes when needed, and that negative/source-gap answers name the checked
268
+ sources instead of making absolute claims over unqueryable artifacts. It writes:
269
+
270
+ ```text
271
+ evals/askmonarch_answer_quality_results.json
272
+ evals/askmonarch_answer_quality_findings.md
273
+ evals/askmonarch_answer_quality_ledger.html
274
+ ```
275
+
276
+ Each ledger case must explain what failed, why it failed, how the correction was
277
+ made durable, and the exact verification command that proves the correction.
278
+ See `evals/askmonarch_quality_probe_summary_2026-05-03.md` and
279
+ `evals/askmonarch_quality_probe_summary_2026-05-03.html` for the May 3 hard
280
+ probe refresh summary.
281
+
282
+ ### 1. Fix the agent instructions
283
+
284
+ Update the `$askmonarch` skill when Codex or Claude misunderstood the question
285
+ or chose the wrong source.
286
+
287
+ Example: if someone asks "how many mosquitoes have we used?" the skill should
288
+ say to use the assay ledger's `n_mosquitoes` field, not CSV frame rows.
289
+
290
+ Example: if someone asks "what compounds does Monarch have in inventory?", the
291
+ skill should route to `compound_inventory` and count or list `Master!D`
292
+ compound names, not bucket search snippets. If they ask "where is X?", return
293
+ the matched `Master` row fields such as Location/Bin, Vendor, CAS, Quantity,
294
+ SDS, and cell provenance.
295
+
296
+ Example: if someone asks "what experiments were run today?", the skill should
297
+ resolve today to an absolute date, check the assay ledger by experiment date,
298
+ then separately check bucket object updates for new uploaded or processed data.
299
+ If the two disagree, say that run date and upload date are different clocks.
300
+
301
+ ### 2. Fix the shared rulebook
302
+
303
+ Update the README or spec when the rule should be visible to everyone working
304
+ on Ask Monarch.
305
+
306
+ Example: if presentations are queryable only from January 1, 2026 onward, the
307
+ spec should say that clearly so future agents do not treat every old deck as
308
+ source-grade.
309
+
310
+ ### 3. Fix the tool
311
+
312
+ Add or improve an API/CLI command when the same question will come up again and
313
+ should not depend on a fresh ad hoc SQL query each time.
314
+
315
+ Example: if animal-use questions become common, add a command like
316
+ `ask-monarch animal-use mosquitoes` that always uses the right ledger field and
317
+ returns the right evidence.
318
+
319
+ For most Monarch teammates, the workflow stays simple: ask through Codex,
320
+ Claude, or another agent and inspect the evidence. Behind the scenes, the agent
321
+ uses the skill and `ask-monarch` CLI. Power users can also use the remote CLI
322
+ directly. Everyone benefits when recurring corrections are captured in these
323
+ shared layers.
324
+
325
+ ## Hosted Service
326
+
327
+ Ask Monarch is deployed on a Google Compute Engine VM.
328
+
329
+ | Piece | Value |
330
+ | --- | --- |
331
+ | VM | `ask-monarch-server` |
332
+ | Google Cloud project | `gen-lang-client-0407939408` |
333
+ | Zone | `us-central1-a` |
334
+ | Repo clone on VM | `/home/josh/ask-monarch` |
335
+ | Public HTTPS endpoint | `https://ask-monarch.34.121.138.236.sslip.io` |
336
+ | Local VM service | `http://127.0.0.1:8787` |
337
+ | Systemd service | `ask-monarch-http.service` |
338
+
339
+ The service is read-only. Public traffic enters through HTTPS and bearer-token
340
+ auth, then nginx proxies to the private localhost service on the VM.
341
+
342
+ Health check:
343
+
344
+ ```bash
345
+ curl -H "Authorization: Bearer $ASK_MONARCH_TOKEN" \
346
+ https://ask-monarch.34.121.138.236.sslip.io/health
347
+ ```
348
+
349
+ Unauthenticated requests should return `401`.
350
+
351
+ ## Team Onboarding
352
+
353
+ Do not send broad team invites until the clean-teammate simulation passes and
354
+ the Codex app, Codex terminal, Claude app, and Claude Code terminal surfaces
355
+ are verified or explicitly recorded as manually confirmed.
356
+
357
+ Admin preflight:
358
+
359
+ ```bash
360
+ python3 scripts/simulate_teammate_onboarding.py --mode temp-home
361
+ ```
362
+
363
+ The simulator creates a fresh one-time setup code, installs into a fake clean
364
+ home, verifies Codex and Claude global setup, runs `ask-monarch doctor`, runs
365
+ source-plane parity checks, and asks canonical Monarch questions for answer
366
+ parity. It writes reports under `output/onboarding-simulations/`.
367
+
368
+ For each teammate, create one personal setup code:
369
+
370
+ ```bash
371
+ ask-monarch onboarding-code create --email person@monarchcrops.com --label "Person setup" --ttl-hours 168
372
+ ```
373
+
374
+ Send that teammate only their own install command:
375
+
376
+ ```bash
377
+ ASK_MONARCH_SETUP_CODE='MNR-XXXX-YYYY' bash -c 'curl -fsSL https://ask-monarch.34.121.138.236.sslip.io/install.sh | bash'
378
+ ask-monarch doctor
379
+ ```
380
+
381
+ After installation, they should open a fresh Codex or Claude thread before
382
+ asking Monarch questions.
383
+
384
+ ## Source Inspection
385
+
386
+ You can also pull up assay videos during Q&A. A useful Ask Monarch answer should
387
+ not stop at a numeric result when the underlying assay is inspectable. When an
388
+ answer identifies an exact assay row, source video path, or filename, the CLI can
389
+ resolve the linked raw video from the verified bucket index, download it into the
390
+ local media cache, and open it:
391
+
392
+ ```bash
393
+ ask-monarch assay-media --filename IMG_0049_Contact_3PP.mov --open
394
+ ask-monarch assay-media --row 1255 --source-name mosquitoes/Mosquito_DART_assay_Results_GCS.xlsx --sheet Assays --open
395
+ ```
396
+
397
+ This is the explicit raw-media exception path. Ask Monarch still answers from
398
+ verified source indexes first; raw videos are opened only after the indexed
399
+ source record has been resolved. If a raw video is not linked yet, the command
400
+ returns diagnostics instead of pretending the video is available.
401
+
402
+ Assay metric overlays are the next inspectable layer. When an assay has processed
403
+ metrics, Ask Monarch should be able to move from:
404
+
405
+ ```text
406
+ Peak mean avoidance was 0.683 at 05:30.
407
+ ```
408
+
409
+ to:
410
+
411
+ ```text
412
+ Peak mean avoidance was 0.683 at 05:30.
413
+ Source: advanced_metrics.csv#row=6.
414
+ Artifact: raw assay video with the avoidance curve overlaid.
415
+ ```
416
+
417
+ The `assay-overlay` command does that for supported processed metric CSVs. DART
418
+ and related tube assays use `advanced_metrics.csv` with `T*_avoidance` columns.
419
+ Contact/non-contact repellency videos use `frame_metrics.csv` with `contact_pi`
420
+ and inside/on-band/outside counts. The command resolves the matching raw video
421
+ from the verified bucket index and renders a synced time-lapse overlay. The
422
+ answer source is still the verified SQLite row; the overlay is an inspection
423
+ artifact. Today this runs from the repo/VM environment where the verified SQLite
424
+ index is present. With `--open`, local assay videos and rendered overlays open
425
+ in a browser player.
426
+
427
+ ```bash
428
+ ask-monarch assay-overlay \
429
+ --metric-csv 'mosquitoes/processed/_2026_04_28_14_44_46_BHomocyclo3_mov_results/_2026_04_28_14_44_46_BHomocyclo3_mov_results/advanced_metrics.csv' \
430
+ --output videos/out/mosquito-bhomocyclo-overlay.mp4 \
431
+ --speed 15 \
432
+ --open
433
+ ```
434
+
435
+ The renderer automatically discovers `T*_avoidance` columns, narrows to the
436
+ assay tubes when source metadata declares them, resolves the raw video object,
437
+ downloads it into `videos/source/`, and prints a proof payload with the peak row,
438
+ timestamp, source CSV provenance, raw media URI, and output video probe.
439
+
440
+ Fast verification:
441
+
442
+ ```bash
443
+ python3 scripts/verify_assay_metric_overlays.py
444
+ ```
445
+
446
+ Two verified examples:
447
+
448
+ ```bash
449
+ # Fly repellency: 2PP, treatment tubes T5-T8, peak 50:30 / 0.654
450
+ ask-monarch assay-overlay \
451
+ --metric-csv 'flies/processed/2026-04-22 12-12-14_results/2026-04-22 12-12-14_results/advanced_metrics.csv' \
452
+ --output videos/out/fly-2pp-overlay.mp4 \
453
+ --speed 30 \
454
+ --open
455
+
456
+ # Mosquito DART: BHomocyclo, tubes T1-T3, peak 05:30 / 0.683
457
+ ask-monarch assay-overlay \
458
+ --metric-csv 'mosquitoes/processed/_2026_04_28_14_44_46_BHomocyclo3_mov_results/_2026_04_28_14_44_46_BHomocyclo3_mov_results/advanced_metrics.csv' \
459
+ --output videos/out/mosquito-bhomocyclo-overlay.mp4 \
460
+ --speed 15 \
461
+ --open
462
+
463
+ # Fly non-contact repellency: 2PP, frame-level contact_pi
464
+ ask-monarch assay-overlay \
465
+ --metric-csv 'contact_repel_videos/flies/processed/2PP_non_contact/frame_metrics.csv' \
466
+ --output videos/out/fly-2pp-non-contact-overlay.mp4 \
467
+ --speed 15 \
468
+ --open
469
+ ```
470
+
471
+ The R&D presentation lane is openable too. Indexed Monarch update decks start
472
+ with the January 2, 2026 presentation, and `ask-monarch presentation --open`
473
+ opens the matching Google Slides locator returned by the verified presentations
474
+ index:
475
+
476
+ ```bash
477
+ ask-monarch presentation --latest --open
478
+ ask-monarch presentation --date 2026-01-02 --open
479
+ ask-monarch presentation --query "3-Step Process" --open
480
+ ```
481
+
482
+ Every query row that has source provenance can also return `source_actions`.
483
+ Those actions are the provenance resolver layer: they do not change the answer
484
+ source, which remains verified SQLite3, but they tell a client how to inspect the
485
+ underlying artifact when one is available. A returned action can point to a raw
486
+ video, Google Slides deck or slide, transcript annotation, CSV row, workbook
487
+ cell, PDF page, image, assay metric overlay, or other artifact. Power users can
488
+ open any returned locator directly:
489
+
490
+ ```bash
491
+ ask-monarch resolve-source --locator 'https://docs.google.com/presentation/d/.../edit#slide=2' --open
492
+ ask-monarch resolve-source --locator 'gs://monarch-videos-new/path/to/video.mov' --open
493
+ ask-monarch assay-overlay --locator 'gs://monarch-videos-new/path/to/advanced_metrics.csv#row=6' --open
494
+ ask-monarch assay-overlay --locator 'gs://monarch-videos-new/path/to/frame_metrics.csv#row=10' --open
495
+ ```
496
+
497
+ The installer saves the token locally at `~/.config/ask-monarch/config.json`.
498
+ To reconfigure it later:
499
+
500
+ ```bash
501
+ ask-monarch configure
502
+ ```
503
+
504
+ See [docs/remote-cli.md](docs/remote-cli.md) for the full CLI reference.
505
+
506
+ ## Agent Skills
507
+
508
+ This repo owns the agent skills/instructions that make the experience feel like
509
+ asking the company rather than running a database query:
510
+
511
+ ```text
512
+ skills/askmonarch/SKILL.md
513
+ skills/braintrust/SKILL.md
514
+ skills/correction/SKILL.md
515
+ skills/monarch-source/SKILL.md
516
+ ```
517
+
518
+ The hosted installer writes:
519
+
520
+ - Codex global instructions: `~/.codex/AGENTS.md`
521
+ - Codex skills: `~/.codex/skills/`
522
+ - Claude global instructions: `~/.claude/CLAUDE.md`
523
+ - Claude skill: `~/.claude/skills/ask-monarch/`
524
+
525
+ Install or refresh repo-owned Codex skills on the VM with:
526
+
527
+ ```bash
528
+ python3 scripts/install_codex_skills.py
529
+ ```
530
+
531
+ `monarch-source` defines when a Monarch artifact becomes source-grade.
532
+ `$askmonarch` is the conversational front door over source-grade Monarch memory.
533
+ `correction` defines what to do when an Ask Monarch answer needs a durable
534
+ routing or answer fix. `braintrust` defines the Ask Monarch trace inspection and
535
+ verification workflow. The canonical text is host-agnostic: Codex, Claude,
536
+ Gemini, Pi, OpenCode, and other agents should follow the same source-routing
537
+ contract when they can run the CLI or call the hosted service.
538
+
539
+ ## Source Lanes
540
+
541
+ ### Bucket
542
+
543
+ - Source id: `monarch_videos_new`
544
+ - Bucket: `gs://monarch-videos-new`
545
+ - Project: `gen-lang-client-0407939408`
546
+ - Parser: `scripts/source_pipeline.py`
547
+ - Verification: `scripts/verify_source_complete.py`
548
+ - Index on VM: `/home/josh/ask-monarch/artifacts/monarch-videos-new/source_index.sqlite`
549
+
550
+ Useful commands:
551
+
552
+ ```bash
553
+ python3 scripts/parse_monarch_bucket.py --manifest-only
554
+ python3 scripts/source_pipeline.py init
555
+ python3 scripts/source_pipeline.py parse --lane structured
556
+ python3 scripts/source_pipeline.py parse --lane video
557
+ python3 scripts/source_pipeline.py parse --lane model
558
+ python3 scripts/source_pipeline.py parse --lane pdf
559
+ python3 scripts/source_pipeline.py parse --lane image
560
+ python3 scripts/source_pipeline.py build-derived
561
+ python3 scripts/source_pipeline.py status
562
+ python3 scripts/verify_source_complete.py
563
+ ```
564
+
565
+ `build-derived` creates the typed assay tables used for exact Q&A, including
566
+ `dart_assay_results` and `assay_media_links`. `assay_media_links` is the
567
+ source-grade bridge from an exact assay record, or indexed video metadata when a
568
+ typed ledger row is not available, to its raw `gs://` assay video. The remote
569
+ CLI exposes it as `ask-monarch assay-media ... --open`, which can cache and open
570
+ the video for inspection during an Ask Monarch session.
571
+
572
+ ### Presentations
573
+
574
+ - Source id: `monarch_storyboards_presentations_2026`
575
+ - Folder: `Storyboards_Presentations`
576
+ - Folder id: `1-dL59DdeoPySGbqE5cjGqednyp4CIzch`
577
+ - Boundary: Monarch update decks from January 1, 2026 onward
578
+ - Parser: `scripts/parse_storyboards_presentations.py`
579
+ - Query helper: `scripts/query_storyboards_presentations.py`
580
+ - Index on VM: `/home/josh/ask-monarch/artifacts/storyboards-presentations-2026/source_index.sqlite`
581
+ - Receipt: [docs/storyboards-presentations-2026-source.md](docs/storyboards-presentations-2026-source.md)
582
+
583
+ Useful commands:
584
+
585
+ ```bash
586
+ ask-monarch presentation --latest --open
587
+ ask-monarch presentation --date 2026-01-02 --open
588
+ ask-monarch presentation --query "3-Step Process" --open
589
+ python3 scripts/parse_storyboards_presentations.py
590
+ python3 scripts/query_storyboards_presentations.py 2PP --limit 5
591
+ python3 scripts/query_storyboards_presentations.py damage --limit 5
592
+ ```
593
+
594
+ `ask-monarch presentation` resolves decks through the hosted presentations
595
+ source index and opens the Google Slides locator stored in deck or slide
596
+ provenance. This source does not claim the entire historical presentation folder. Older
597
+ decks, PDFs, notebooks, interviews, Teams messages, emails, academic papers, and
598
+ dashboards are future source candidates until they pass the same source gate.
599
+
600
+ ### Monarch Teams Recaps
601
+
602
+ - Source id: `monarch_recurring_teams_recaps`
603
+ - Source lane: `teams_recaps`
604
+ - Source system: Microsoft Teams / Microsoft Graph
605
+ - Boundary: recurring `Monarch R&D` meetings from January 2, 2026 onward, `Monarch Weekly` meetings from May 5, 2026 onward, and `Monarch Team Sync` meetings from May 6, 2026 onward
606
+ - Freshness: VM refresh runs just after midnight America/Los_Angeles and includes meetings through the previous Pacific calendar day
607
+ - Refresher: `scripts/refresh_teams_recaps_source.py`
608
+ - Fetcher: `scripts/fetch_monarch_r_and_d_teams_recaps.py`
609
+ - Parser: `scripts/parse_monarch_r_and_d_teams_recaps.py`
610
+ - Query helper: `scripts/query_monarch_r_and_d_teams_recaps.py`
611
+ - Index on VM: `/home/josh/ask-monarch/artifacts/monarch-r-and-d-teams-recaps/source_index.sqlite`
612
+ - Receipt: [docs/monarch-r-and-d-teams-recaps-source.md](docs/monarch-r-and-d-teams-recaps-source.md)
613
+
614
+ Useful commands:
615
+
616
+ ```bash
617
+ python3 scripts/refresh_teams_recaps_source.py --no-restart
618
+ python3 scripts/query_monarch_r_and_d_teams_recaps.py "spatial repellents" --limit 5
619
+ ```
620
+
621
+ This lane is meeting-transcript memory, not the whole Teams universe. Teams
622
+ messages, channels, company-wide email sources, papers, dashboards, and older
623
+ meeting transcripts remain future source candidates until they pass the same
624
+ source gate. Personal mailbox access, when mapped for a personal token, is a
625
+ private live overlay and does not promote those emails into shared company
626
+ memory.
627
+
628
+ ### Company Profile
629
+
630
+ - Source id: `monarch_company_profile`
631
+ - Source lane: `company_profile`
632
+ - Raw source: `sources/monarch-company-profile/company_profile.json`
633
+ - Parser: `scripts/parse_company_lanes.py`
634
+ - Index on VM: `/home/josh/ask-monarch/artifacts/monarch-company-profile/source_index.sqlite`
635
+ - Receipt: [docs/monarch-company-profile-source.md](docs/monarch-company-profile-source.md)
636
+
637
+ Useful commands:
638
+
639
+ ```bash
640
+ python3 scripts/parse_company_lanes.py
641
+ ask-monarch company-profile-search mission --limit 5
642
+ ask-monarch search "where is Monarch based" --source company_profile --limit 5
643
+ ```
644
+
645
+ This lane is durable company framing, not an automatically discovered corporate
646
+ knowledge base. Update the JSON source when the company framing changes, then
647
+ rerun the parser.
648
+
649
+ ### People Directory
650
+
651
+ - Source id: `monarch_people_directory`
652
+ - Source lane: `people_directory`
653
+ - Raw source: `sources/monarch-people-directory/people_directory.json`
654
+ - Parser: `scripts/parse_company_lanes.py`
655
+ - Index on VM: `/home/josh/ask-monarch/artifacts/monarch-people-directory/source_index.sqlite`
656
+ - Receipt: [docs/monarch-people-directory-source.md](docs/monarch-people-directory-source.md)
657
+
658
+ Useful commands:
659
+
660
+ ```bash
661
+ python3 scripts/parse_company_lanes.py
662
+ ask-monarch people-search Avinash --limit 5
663
+ ask-monarch people-search advisor --kind advisors --limit 20
664
+ ask-monarch sql "select name, role, lane, provenance_grain from units where lane = 'employees' order by name" --source people_directory --limit 50
665
+ ask-monarch sql "select name, role, lane, provenance_grain from units order by lane, name" --source people_directory --limit 50
666
+ ```
667
+
668
+ This lane covers people facts explicitly entered into the source JSON. It should
669
+ not be treated as a full HRIS, inbox, or LinkedIn scrape.
670
+
671
+ ### Company Context
672
+
673
+ - Source id: `monarch_company_context`
674
+ - Source lane: `company_context`
675
+ - Raw source: `sources/monarch-company-context/Monarch_for_askmonarch.pdf`
676
+ - Boundary: exactly this one 22-page PDF file
677
+ - Parser: `scripts/parse_monarch_company_context.py`
678
+ - Index on VM: `/home/josh/ask-monarch/artifacts/monarch-company-context/source_index.sqlite`
679
+ - Receipt: [docs/monarch-company-context-source.md](docs/monarch-company-context-source.md)
680
+
681
+ Useful commands:
682
+
683
+ ```bash
684
+ python3 scripts/parse_monarch_company_context.py
685
+ ask-monarch company-context-search glossary --limit 5
686
+ ask-monarch search "USDA Insecticide Residue Report" --source company_context --limit 5
687
+ ask-monarch sql "select page_number, unit_index, text, provenance_grain from text_units where text like '%USDA%'" --source company_context --limit 20
688
+ ```
689
+
690
+ This is company context sourced from PDF intake evidence. Current
691
+ employee/advisor questions should use `people_directory` first; older names in
692
+ the PDF do not override current people-directory truth.
693
+
694
+ ### Milestones Doc
695
+
696
+ - Source id: `monarch_milestones_doc`
697
+ - Source lane: `milestones_doc`
698
+ - Source system: Google Docs / Google Drive connector
699
+ - Boundary: exactly the `monarch_milestones` Google Doc revision fetched on May 1, 2026
700
+ - Parser: `scripts/parse_monarch_milestones_doc.py`
701
+ - Query helper: `scripts/query_monarch_milestones_doc.py`
702
+ - Index on VM: `/home/josh/ask-monarch/artifacts/monarch-milestones-doc/source_index.sqlite`
703
+ - Receipt: [docs/monarch-milestones-doc-source.md](docs/monarch-milestones-doc-source.md)
704
+
705
+ Useful commands:
706
+
707
+ ```bash
708
+ python3 scripts/parse_monarch_milestones_doc.py
709
+ ask-monarch query "phytotoxicity" --source milestones_doc --limit 5
710
+ ask-monarch milestones-search "62 chemicals" --limit 5
711
+ ask-monarch sql "select paragraph_index, text, provenance_grain from paragraph_units" --source milestones_doc --limit 5
712
+ ```
713
+
714
+ This lane is a document-revision snapshot. Refetch the Google Doc and rerun the
715
+ parser before using it for claims about later milestone edits.
716
+
717
+ ## Querying Locally
718
+
719
+ The hosted path is preferred for shared use. Local scripts are still useful for
720
+ debugging and parser development:
721
+
722
+ ## Braintrust Tracing
723
+
724
+ Ask Monarch query requests emit Braintrust traces when the runtime has the
725
+ Python dependency and an API key:
726
+
727
+ ```bash
728
+ python3 -m pip install -r requirements.txt
729
+ export BRAINTRUST_API_KEY=...
730
+ export ASK_MONARCH_BRAINTRUST_PROJECT=ask-monarch
731
+ export ASK_MONARCH_BRAINTRUST_PROJECT_ID=28216333-66fb-42a6-923b-622bda7a2fcc
732
+ ```
733
+
734
+ Tracing fails open: if the SDK or API key is missing, source queries still run
735
+ and simply omit trace fields. When tracing is active, every `/query` response
736
+ includes a Braintrust full trace URL. The local Braintrust context is stored in
737
+ `.bt/config.json`.
738
+
739
+ ```bash
740
+ python3 scripts/query_source.py --summary
741
+ python3 scripts/query_source.py --q "Preference Index" --kind pdf_page --limit 5
742
+ python3 scripts/query_source.py --csv-q IR3535 --name-like combined_results.csv --limit 5
743
+ python3 scripts/query_source.py --sql "select name, row_number, row_json, provenance_grain from csv_rows_with_provenance where row_json like '%IR3535%' limit 5"
744
+ ```
745
+
746
+ See [docs/querying-monarch-source.md](docs/querying-monarch-source.md).
747
+
748
+ ## Deep Research Max
749
+
750
+ Normal Ask Monarch questions should query verified source indexes directly.
751
+ Deep Research Max is only for long-form external research, literature
752
+ comparison, scientific synthesis, market/context scans, or visual analysis
753
+ grounded in Monarch evidence.
754
+
755
+ Deep Research does this:
756
+
757
+ ```text
758
+ research question -> verified multi-source evidence bundle -> Gemini Deep Research Max -> cited report
759
+ ```
760
+
761
+ The bundle currently includes verified lanes such as `bucket`, `presentations`,
762
+ `teams_recaps`, `company_profile`, `people_directory`, and `company_context`
763
+ when relevant. The `milestones_doc` lane is queryable through the hosted HTTP
764
+ API and remote CLI, but should be added to Deep Research bundles before relying
765
+ on it in that mode.
766
+ If a required source lane is missing or has unverified receipts, Deep Research
767
+ stops before launch instead of producing a partial internal-evidence report.
768
+
769
+ Bundle-only:
770
+
771
+ ```bash
772
+ python3 scripts/deep_research_monarch.py "Compare our 2PP fly and mosquito assay signal against published 2-propylphenol repellency literature."
773
+ ```
774
+
775
+ Launch Gemini Deep Research Max:
776
+
777
+ ```bash
778
+ GEMINI_API_KEY=... python3 scripts/deep_research_monarch.py "Compare our 2PP fly and mosquito assay signal against published 2-propylphenol repellency literature." --launch --wait
779
+ ```
780
+
781
+ Outputs live under:
782
+
783
+ ```text
784
+ reports/deep-research/
785
+ ```
786
+
787
+ See [docs/deep-research-mode.md](docs/deep-research-mode.md).
788
+
789
+ ## Daily Refresh
790
+
791
+ The VM should refresh parsed scheduled source indexes daily just after midnight
792
+ America/Los_Angeles. The scheduled lanes are `bucket`
793
+ (`gs://monarch-videos-new`), `chemistry_analysis`
794
+ (`gs://monarch-chemistry-analysis`), and `teams_recaps` recurring Teams meeting
795
+ transcripts.
796
+
797
+ The main bucket path is incremental: reuse the current verified SQLite index,
798
+ enumerate the live bucket, invalidate only added/changed/deleted objects, parse
799
+ those objects, then verify before replacing the live SQLite files:
800
+
801
+ ```text
802
+ live source -> staged incremental parse -> receipts/gaps -> verification -> atomic swap
803
+ ```
804
+
805
+ Repo-owned pieces:
806
+
807
+ - `scripts/refresh_source_index.py`
808
+ - `scripts/refresh_chemistry_analysis_source.py`
809
+ - `scripts/refresh_teams_recaps_source.py`
810
+ - `scripts/refresh_bucket_sources.py`
811
+ - `deploy/systemd/ask-monarch-refresh.service`
812
+ - `deploy/systemd/ask-monarch-refresh.timer`
813
+ - [docs/daily-source-refresh.md](docs/daily-source-refresh.md)
814
+
815
+ ## Operations
816
+
817
+ VM service commands:
818
+
819
+ ```bash
820
+ sudo systemctl status ask-monarch-http.service
821
+ sudo systemctl restart ask-monarch-http.service
822
+ sudo journalctl -u ask-monarch-http.service -n 100 --no-pager
823
+ sudo systemctl status nginx
824
+ sudo nginx -t
825
+ ```
826
+
827
+ Deploy the latest GitHub code to the VM:
828
+
829
+ ```bash
830
+ gcloud compute ssh ask-monarch-server \
831
+ --project gen-lang-client-0407939408 \
832
+ --zone us-central1-a \
833
+ --command 'cd /home/josh/ask-monarch && git pull --ff-only origin main && python3 scripts/install_codex_skills.py'
834
+ ```
835
+
836
+ ## Repo Layout
837
+
838
+ ```text
839
+ ASKMONARCH-SPEC.md product/source contract
840
+ config/source-map.yaml source registry and query-plane map
841
+ docs/ operating docs and source receipts
842
+ scripts/ parsers, query tools, HTTP service, CLI, refresh
843
+ skills/ repo-owned Codex skills
844
+ deploy/systemd/ VM service and refresh units
845
+ reports/deep-research/ generated Deep Research bundles and reports
846
+ ```
847
+
848
+ Generated source-plane outputs are intentionally not committed to GitHub. Keep
849
+ the repo as code, specs, scripts, skills, and docs. Keep large parsed artifacts
850
+ on the VM or in artifact storage.
851
+
852
+ ## Source Contract
853
+
854
+ A source is not queryable just because it exists. Ask Monarch treats a source as
855
+ queryable only when:
856
+
857
+ - it is listed in `config/source-map.yaml`
858
+ - it can be accessed through an authenticated route
859
+ - its live contents are enumerated
860
+ - its artifacts are parsed into atomic units
861
+ - each unit has source-grade provenance
862
+ - receipt and gap files are written
863
+ - verification passes
864
+ - query tools can return evidence with exact locators
865
+
866
+ That contract is the core of the system: do the hard parsing once, verify it,
867
+ store it in a parsed index, and query the index fast.