Skip to content

Commit 639cdca

Browse files
committed
feat(flow): add codex telemetry and workflow inspection
Add local-first Codex eval, telemetry, and trace inspection commands plus Maple export plumbing. Carry trace metadata through Flow-managed Codex routes, expose repo workflow overview over the local server, and document the operator surfaces. The change is scoped for robustness and performance: local logs and memory remain canonical, export stays redacted and best-effort, codexd only does bounded background refresh/flush work, and env-store fallback lets Flow-managed sessions pick up shared Maple config without leaking repo-specific state.
1 parent 88fb3b5 commit 639cdca

16 files changed

Lines changed: 4916 additions & 173 deletions
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Codex Maple Telemetry Runbook
2+
3+
Use this when you want shared analytics for Flow-guided Codex usage without
4+
changing the local source of truth.
5+
6+
## What This Does
7+
8+
Flow keeps Codex telemetry local first:
9+
10+
- `codex/skill-eval/events.jsonl`
11+
- `codex/skill-eval/outcomes.jsonl`
12+
- Jazz2-backed Codex memory mirror
13+
14+
Optional Maple export reads those local logs and emits a derived, redacted OTLP
15+
stream.
16+
17+
What gets exported:
18+
19+
- route / mode / action
20+
- runtime skill names and counts
21+
- prompt/context size metrics
22+
- reference counts
23+
- outcome kind / success
24+
- repo leaf name plus hashed path identifiers
25+
26+
What does not get exported:
27+
28+
- raw prompt text
29+
- full filesystem paths
30+
- raw session ids
31+
32+
## Configure
33+
34+
Use Flow env store so the daemon and Flow-launched Codex sessions see the same
35+
values. For local-only secrets, prefer the personal store:
36+
37+
```bash
38+
cd ~/code/flow
39+
f env set --personal FLOW_CODEX_MAPLE_LOCAL_ENDPOINT=http://ingest.maple.localhost/v1/traces
40+
f env set --personal FLOW_CODEX_MAPLE_LOCAL_INGEST_KEY=maple_pk_local_xxx
41+
f env set --personal FLOW_CODEX_MAPLE_HOSTED_ENDPOINT=https://ingest.maple.dev/v1/traces
42+
f env set --personal FLOW_CODEX_MAPLE_HOSTED_INGEST_KEY=maple_sk_hosted_xxx
43+
f env set --personal FLOW_CODEX_MAPLE_HOSTED_PUBLIC_INGEST_KEY=maple_pk_hosted_xxx
44+
```
45+
46+
Optional tuning:
47+
48+
```bash
49+
f env set --personal FLOW_CODEX_MAPLE_SERVICE_NAME=flow-codex
50+
f env set --personal FLOW_CODEX_MAPLE_SCOPE_NAME=flow.codex
51+
f env set --personal FLOW_CODEX_MAPLE_ENV=local
52+
f env set --personal FLOW_CODEX_MAPLE_QUEUE_CAPACITY=1024
53+
f env set --personal FLOW_CODEX_MAPLE_MAX_BATCH_SIZE=64
54+
f env set --personal FLOW_CODEX_MAPLE_FLUSH_INTERVAL_MS=100
55+
f env set --personal FLOW_CODEX_MAPLE_CONNECT_TIMEOUT_MS=400
56+
f env set --personal FLOW_CODEX_MAPLE_REQUEST_TIMEOUT_MS=800
57+
```
58+
59+
On macOS, personal env reads may require a daily unlock:
60+
61+
```bash
62+
f env unlock
63+
```
64+
65+
If you launch Codex through Flow (`j ...`, `f codex ...`, `k ...`), Flow will
66+
hydrate these `FLOW_CODEX_MAPLE_*` vars into the child Codex process. Explicit
67+
shell env vars override the personal store for that launch, which makes one-off
68+
telemetry tests quiet and deterministic.
69+
70+
From inside a Codex session, the write path stays the same:
71+
72+
```bash
73+
f env set --personal FLOW_CODEX_MAPLE_HOSTED_ENDPOINT=...
74+
f env set --personal FLOW_CODEX_MAPLE_HOSTED_INGEST_KEY=...
75+
f env get --personal FLOW_CODEX_MAPLE_HOSTED_ENDPOINT
76+
```
77+
78+
## Run
79+
80+
Inspect current state:
81+
82+
```bash
83+
f codex telemetry status
84+
```
85+
86+
Flush unseen local telemetry once:
87+
88+
```bash
89+
f codex telemetry flush --limit 200
90+
```
91+
92+
Equivalent task shortcuts:
93+
94+
```bash
95+
f codex-telemetry-status
96+
f codex-telemetry-flush
97+
```
98+
99+
## Background Export
100+
101+
If `codexd` is running, it also performs a bounded background flush pass during
102+
its normal maintenance loop. This keeps export cheap and avoids a separate
103+
always-on process.
104+
105+
## Notes
106+
107+
- Export is derived and best-effort.
108+
- Local logs and memory stay canonical even if Maple is unavailable.
109+
- This is intended for route/context/outcome analytics, not transcript export.

docs/commands/ai.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,17 @@ Codex usage history without replaying Codex in the hot path.
218218
Useful commands:
219219

220220
```bash
221+
f codex eval --path ~/work/example-project
221222
f codex memory sync --limit 400
222223
f codex memory recent --path ~/work/example-project --limit 12
223224
f codex skill-eval show --path ~/work/example-project
224225
f codex skill-eval run --path ~/work/example-project
225226
f codex skill-eval cron --limit 400 --max-targets 12 --within-hours 168
227+
f codex telemetry status
228+
f codex telemetry flush --limit 200
229+
f codex trace status
230+
f codex trace current-session --json
231+
f codex trace inspect <trace-id> --json
226232
f codex skill-source list --path ~/work/example-project
227233
f codex skill-source sync --path ~/work/example-project --skill find-skills
228234
```
@@ -250,6 +256,76 @@ What `cron` does:
250256

251257
For your use case, this keeps learning cheap and safe enough to run regularly.
252258

259+
### Trace inspection for Flow-managed Codex sessions
260+
261+
Flow now assigns a trace envelope to all Flow-managed Codex launches, not just
262+
special workflows like `check <github-pr-url>`.
263+
264+
That means sessions started or resumed through:
265+
266+
```bash
267+
j ...
268+
k <session-id>
269+
f codex open ...
270+
f codex resume ...
271+
f codex continue ...
272+
```
273+
274+
carry `FLOW_TRACE_*` env vars and emit at least one compact Flow telemetry
275+
event, so the session becomes remotely inspectable.
276+
277+
Useful commands:
278+
279+
```bash
280+
f codex trace status
281+
f codex trace current-session --json
282+
f codex trace inspect <trace-id> --json
283+
```
284+
285+
Behavior:
286+
287+
- `trace status` checks whether Maple MCP reads are configured and reachable
288+
- `trace current-session` reads the active `FLOW_TRACE_ID` from the current
289+
Flow-managed Codex session, flushes recent Flow telemetry once, then attempts
290+
a remote trace read
291+
- if Maple reads are partially configured but tenant access is still blocked,
292+
Flow returns the current trace metadata plus `readError` instead of failing
293+
without context
294+
295+
This keeps the workflow autonomous from inside Codex itself: once the session
296+
was started through Flow, you can inspect the current trace without manually
297+
copying ids.
298+
299+
`f codex eval --path ...` is the joined operator report:
300+
301+
- current runtime/doctor state
302+
- recent route mix and context cost
303+
- grounded skill scorecard highlights
304+
- concrete “what to improve next” recommendations
305+
- commands to deepen or fix the current state
306+
307+
If `codexd` is running, it also keeps recent completion reconciliation warm and
308+
now does a bounded background scorecard refresh, so the eval report does not go
309+
stale as quickly between manual runs.
310+
311+
Optional telemetry export follows the same local-first pattern: Flow keeps
312+
local Codex logs canonical, and if `FLOW_CODEX_MAPLE_*` env vars are set it can
313+
export redacted route/context/outcome spans to Maple without shipping raw
314+
prompts or full repo paths. Use:
315+
316+
```bash
317+
f codex telemetry status
318+
f codex telemetry flush --limit 200
319+
```
320+
321+
For local-only secrets, prefer `f env set --personal ...`. On macOS you may
322+
need `f env unlock` once per day for background reads. Flow-launched Codex
323+
sessions also inherit the same `FLOW_CODEX_MAPLE_*` values from the personal
324+
store, while explicit shell env still wins for one-off tests.
325+
326+
When `codexd` is running, the daemon also performs a bounded background export
327+
pass so the external analytics view stays warm.
328+
253329
### macOS launchd schedule for skill-eval
254330

255331
If you want scorecards to stay fresh automatically on macOS:

flow.toml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,16 @@ name = "codex-skill-eval-launchd-logs"
402402
command = "python3 ./scripts/codex-skill-eval-launchd.py logs $@"
403403
description = "Show scheduled Codex skill-eval launch agent logs"
404404

405+
[[tasks]]
406+
name = "codex-telemetry-status"
407+
command = "f codex telemetry status $@"
408+
description = "Show optional redacted Codex telemetry export state"
409+
410+
[[tasks]]
411+
name = "codex-telemetry-flush"
412+
command = "f codex telemetry flush $@"
413+
description = "Flush unseen redacted Codex telemetry to configured Maple endpoints once"
414+
405415
[[tasks]]
406416
name = "test-args"
407417
command = "echo \"arg1=$1 arg2=$2 all=$@\""
@@ -496,6 +506,24 @@ variables = [
496506
{ key = "FLOW_ROUTER_OVERRIDE_REASON", default = "" },
497507
{ key = "FLOW_RL_SIGNAL_TEXT", default = "snippet" },
498508
{ key = "FLOW_RL_SIGNAL_MAX_CHARS", default = "4000" },
509+
{ key = "FLOW_CODEX_MAPLE_LOCAL_ENDPOINT", default = "" },
510+
{ key = "FLOW_CODEX_MAPLE_LOCAL_INGEST_KEY", default = "" },
511+
{ key = "FLOW_CODEX_MAPLE_HOSTED_ENDPOINT", default = "" },
512+
{ key = "FLOW_CODEX_MAPLE_HOSTED_INGEST_KEY", default = "" },
513+
{ key = "FLOW_CODEX_MAPLE_HOSTED_PUBLIC_INGEST_KEY", default = "" },
514+
{ key = "FLOW_CODEX_MAPLE_TRACES_ENDPOINTS", default = "" },
515+
{ key = "FLOW_CODEX_MAPLE_INGEST_KEYS", default = "" },
516+
{ key = "FLOW_CODEX_MAPLE_SERVICE_NAME", default = "flow-codex" },
517+
{ key = "FLOW_CODEX_MAPLE_SERVICE_VERSION", default = "" },
518+
{ key = "FLOW_CODEX_MAPLE_SCOPE_NAME", default = "flow.codex" },
519+
{ key = "FLOW_CODEX_MAPLE_ENV", default = "local" },
520+
{ key = "FLOW_CODEX_MAPLE_QUEUE_CAPACITY", default = "1024" },
521+
{ key = "FLOW_CODEX_MAPLE_MAX_BATCH_SIZE", default = "64" },
522+
{ key = "FLOW_CODEX_MAPLE_FLUSH_INTERVAL_MS", default = "100" },
523+
{ key = "FLOW_CODEX_MAPLE_CONNECT_TIMEOUT_MS", default = "400" },
524+
{ key = "FLOW_CODEX_MAPLE_REQUEST_TIMEOUT_MS", default = "800" },
525+
{ key = "MAPLE_API_TOKEN", default = "" },
526+
{ key = "MAPLE_MCP_URL", default = "https://api.maple.dev/mcp" },
499527
{ key = "SEQ_CH_MEM_PATH", default = "~/.config/flow/rl/seq_mem.jsonl" },
500528
{ key = "HARBOR_DIR", default = "~/repos/laude-institute/harbor" },
501529
]

0 commit comments

Comments
 (0)