Symptom
When the Python SDK bootstraps (via @watch() or any patch_*() → ensure_initialised()), it does not honor the TJ_CONFIG environment variable for config discovery. A process that sets TJ_CONFIG to point at a project/custom config can silently initialize against the global config and write spans into the global DuckDB instead of the intended one.
Observed: a pilot run with TJ_CONFIG set briefly wrote spans into the global DB before being cleaned up (0 left behind, but the isolation failure is the bug).
Root cause (confirmed in code)
tokenjam/sdk/bootstrap.py:ensure_initialised() calls load_config() with no path argument. The CLI path passes --config / goes through a discovery that honors TJ_CONFIG; the SDK bootstrap path does not, so a custom TJ_CONFIG is ignored. (Fixer to confirm whether the fix belongs in load_config()'s env handling or in ensure_initialised() passing the resolved path.)
Acceptance criteria
ensure_initialised() respects TJ_CONFIG (and the documented discovery order: tj.toml → .tj/config.toml → ~/.config/tj/config.toml) so SDK-instrumented processes write to the intended DB.
- Test: set
TJ_CONFIG to a temp config, exercise a patch_*/@watch path, assert spans land in the temp DB and not the global one.
Scope / out of scope
- In scope: SDK bootstrap config discovery.
- Out of scope: CLI config discovery (already honors
TJ_CONFIG).
Severity
Medium. Data-isolation hazard: any SDK user (or an agent running an instrumentation experiment) with a custom config can unknowingly pollute the global telemetry DB.
Discovered during a real-agent instrumentation pilot.
Symptom
When the Python SDK bootstraps (via
@watch()or anypatch_*()→ensure_initialised()), it does not honor theTJ_CONFIGenvironment variable for config discovery. A process that setsTJ_CONFIGto point at a project/custom config can silently initialize against the global config and write spans into the global DuckDB instead of the intended one.Observed: a pilot run with
TJ_CONFIGset briefly wrote spans into the global DB before being cleaned up (0 left behind, but the isolation failure is the bug).Root cause (confirmed in code)
tokenjam/sdk/bootstrap.py:ensure_initialised()callsload_config()with no path argument. The CLI path passes--config/ goes through a discovery that honorsTJ_CONFIG; the SDK bootstrap path does not, so a customTJ_CONFIGis ignored. (Fixer to confirm whether the fix belongs inload_config()'s env handling or inensure_initialised()passing the resolved path.)Acceptance criteria
ensure_initialised()respectsTJ_CONFIG(and the documented discovery order:tj.toml→.tj/config.toml→~/.config/tj/config.toml) so SDK-instrumented processes write to the intended DB.TJ_CONFIGto a temp config, exercise apatch_*/@watchpath, assert spans land in the temp DB and not the global one.Scope / out of scope
TJ_CONFIG).Severity
Medium. Data-isolation hazard: any SDK user (or an agent running an instrumentation experiment) with a custom config can unknowingly pollute the global telemetry DB.
Discovered during a real-agent instrumentation pilot.