Add versioned computation trace export (policyengine.trace.v1)#515
Add versioned computation trace export (policyengine.trace.v1)#515edithatogo wants to merge 3 commits into
Conversation
MaxGhenis
left a comment
There was a problem hiding this comment.
Thanks for this — it's a clean, well-scoped, and genuinely well-tested contribution, and computation provenance is a direction we actively want to build out. I reviewed the diff in full and ran the suite locally against master.
What works well
- No hot-path cost.
to_trace()builds on the existingget_serialized_flat_trace()and only runs when explicitly called; it's gated onFullTracer, andSimpleTracerstays the default, so tracing-disabled simulations pay nothing. Theraise ValueErrorguard inSimulation.to_tracemakes the requirement explicit. That's exactly the compatibility posture core needs, since every country model sits on it. - Forward-compatible versioning. A top-level
formatstring plus a hardValueErroron anything butpolicyengine.trace.v1is the right way to keep the document evolvable. - Grounded in existing surfaces.
_engine_metadata()readsget_runtime_metadata()and the{name, version, git_sha}keys line up; node/parameter ids reuseFlatTrace.key(); the changelog fragment is present. - Verified locally:
tests/core/test_tracers.py→ 45 passed;test_simulations.py+test_tracers.pyregression → 51 passed.
Suggestions (non-blocking)
- Recover structured fields from
TraceNode, not the string key.to_trace()buildscalculation.rootsfrom structured node attributes (tree.name,tree.period,tree.branch_name) but buildsnodesby regex-parsing the serialized key viaparse_trace_key. The regex assumes branch names contain no parentheses and periods no angle brackets — true today, but it couples the export to the exact string format. Sincebrowse_trace()already yieldsTraceNodes with these fields structured, consider buildingnodesfrom those directly and keepingparse_trace_keyonly for the flat parameter-key map (which has no node object to read from). calculationentity/count + parameter source metadata. #512's "minimum useful fields" also listed entity/count oncalculationand source/version on parameters;rootscurrently omit entity/count andparametersomit source/version. Fine to defer — worth a line in the format notes so consumers know they're intentionally v1-absent.- Value size at population scale. Nodes embed the full serialized vector, which is ideal for the household-audit case in #512; for population traces it can get large. #512 mentioned "values or summaries," so an optional summarization/threshold could follow later.
- Coordinate with the existing
policyengine.pytrace surface.policyenginealready shipspolicyengine.provenance, which emits TRACE Transparent Research Objects (JSON-LD, TROv vocab, namespacehttps://policyengine.org/trace/0.1#) that pin the model wheel, dataset, manifest, and reform by sha256 — i.e. release/composition provenance. This PR'spolicyengine.trace.v1is per-computation provenance, so the two are complementary rather than overlapping, but both live under the PolicyEngine "trace" name. Two things would help: (a) confirm thepolicyengine.trace.v1format id and the…/trace/0.1#TRO namespace are intentionally distinct, and (b) note that a per-simulation TRO could embed or reference apolicyengine.trace.v1document as its runtime payload — that composition is the natural end state for provenance visualization. A short written schema forpolicyengine.trace.v1(pairs well with #517) would also make the format consumable downstream.
CI status
No checks have run yet — the status rollup is empty because this is a first-time fork contribution and GitHub is holding the workflow runs for maintainer approval (not a pass/fail). The touched code exercises tests/core unit tests plus a docs build, none of which need repository secrets, so Lint / check-changelog / Test should go green once a maintainer approves the run; only the multi-package smoke test is occasionally fork-flaky.
Overall this is close, and I'd be glad to see it land after the structured-field cleanup and a quick maintainer call on the format/namespace coordination in (4).
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #515 +/- ##
==========================================
+ Coverage 84.69% 86.12% +1.42%
==========================================
Files 223 230 +7
Lines 11830 12883 +1053
Branches 1169 1253 +84
==========================================
+ Hits 10019 11095 +1076
+ Misses 1496 1444 -52
- Partials 315 344 +29 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Expose FullTracer.to_trace() and Simulation.to_trace() over the existing FlatTrace serialization so household calculations can export a stable, JSON-compatible audit document without changing formula evaluation. Closes PolicyEngine#512
Raise patch coverage for the versioned trace export helpers that Codecov flagged on PR PolicyEngine#515. Co-authored-by: Cursor <cursoragent@cursor.com>
768c986 to
7bedc2c
Compare
|
Pushed additional unit tests covering |
Address review feedback: avoid regex-parsing flat keys for node identity, document v1-absent fields and TRO complementarity, keep parse_trace_key for flat-key callers only. Co-authored-by: Cursor <cursoragent@cursor.com>
Follow-up to @MaxGhenis reviewAddressed the structured-field cleanup and format notes:
Also: CI still shows no checks — first-time fork contribution. Could you approve the workflow runs when you have a moment so Lint/Test can go green? Happy to iterate further if you want a separate short schema page (pairs with #517) before merge. |
What's changed
Closes #512.
Adds an opt-in, versioned JSON-compatible computation trace export:
FullTracer.to_trace(format="policyengine.trace.v1")exports calculation roots, structured nodes, dependencies, parameter reads, values, and timings.Simulation.to_trace()requirestrace=Trueand adds best-effort model metadata.ValueError.TraceNodefields rather than parsing display keys.The export does not alter formula evaluation, add an external schema dependency, or impose tracing cost when tracing is disabled.
Verification
pytest tests/core/test_tracers.pypasses locally (45 tests at the recorded revision).make format && make documentationawaits the upstream workflow run.Compatibility, performance, and limits
The API is opt-in and built from the existing tracer. V1 intentionally omits calculation entity/count and parameter source/version metadata. Full vector values may be large for population-scale traces; summarization is deferred. The identifier is distinct from PolicyEngine's TRACE Transparent Research Object namespace: this PR covers per-computation provenance, while TRO covers release/composition provenance.
Maintainer action required
GitHub is holding workflow execution for this first-time fork contribution. Please approve the non-secret workflow run and confirm the
policyengine.trace.v1identifier before merge.