datasets: define the agent-trace schema and seed the first entries - #62
Open
gautamgb wants to merge 1 commit into
Open
datasets: define the agent-trace schema and seed the first entries#62gautamgb wants to merge 1 commit into
gautamgb wants to merge 1 commit into
Conversation
agentdataflow_toolexchange_traces/ has been open for contributions with a TODO where its data format should be. This defines the format, ships the tooling to enforce it, and seeds two entries so the schema is grounded in real traces rather than designed in the abstract. The schema carries an explicit provenance tier - sanitized production, lab/CTF, derived-from-public-observation, or hypothetical - because the people who hold real agent traces mostly cannot publish them. Every tier above hypothetical requires a citation, enforced by validate.py, so the three kinds of contribution never pretend to be one another. The category enum matches the values already used by the repo's central data_validation/schemas/agentdataflow_trace.schema.json. Where this schema diverges from that one, the divergence is deliberate and set out in the pull request description. validate.py checks schema conformance, the span graph, provenance coherence, and ISO dates, and scans every string in the entry - not only span payloads - for credential- and PII-shaped values, independently of the contributor's sanitization attestation.
gautamgb
force-pushed
the
dataset/agent-traces-schema-and-seed
branch
from
August 7, 2026 21:02
aece5f8 to
b14e220
Compare
Author
|
Revised the description and force-pushed a corrected commit before anyone had to read the first one. Self-review turned up three things: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Defines a data format for
datasets/agentdataflow_toolexchange_traces/, ships the tooling to enforce it, and seeds the first entries so the schema is grounded in real traces rather than designed in the abstract. The folder's README currently carries a<!-- TODO: Define schema once initial data is contributed -->where its format should be.Supports the Data Collection and Data Validation workstreams.
schema.jsonvalidate.pybuild_index.py/index.csvexploit_datasetexample.jsonentries/(2)README.mdFirst: there is already a schema for this dataset
data_validation/schemas/agentdataflow_trace.schema.jsonexists and defines this dataset. I did not see it before starting, and you should have that fact up front rather than discover it in review.Having found it, the situation looks less like a duplicate and more like something worth deciding deliberately.
The repo already has two schema systems, and they already disagree - before this PR.
datasets/exploit_dataset/ships its ownschema.jsonwith seven live entries validated against it. Those same entries faildata_validation/schemas/exploit.schema.json. Taking the mergedentries/AML.T0010.jsonagainst the central schema:The central
data_validation/schemas/*.jsondescribe an earlier design - sequentialEXP-0001identifiers, scalarimpact,sourceas a single string - that the dataset-local schemas superseded in practice. The dataset-local one is the one with data behind it. That is the precedent this PR follows.What I aligned. The
categoryenum now uses the central schema's values, since that divergence was free to give up:What I kept, and why. These are genuine disagreements rather than cosmetic ones:
trace_id^TRACE-\d{4}$DSGAI-TRACE-<slug>exploit_datasetabandonedEXP-\d{4}for the same reason.trace_data, array of untyped objectsspans, typedtype: benign / adversarialdisposition, plusunintentional_failuretypebecause a property calledtypeinside a JSON Schema reads badly.security_observations: stringsensitivity_annotations: top-level arraydata_classes+sensitivityWhat I would like from you is a direction, not a decision in this PR. Three options:
data_validation/schemas/agentdataflow_trace.schema.jsonwith a pointer to the dataset-local one, and file an issue recording the same drift forexploit_dataset.I would suggest 2, and I am happy to do the work.
The design decision worth your review: provenance tiers
This dataset has been open for contributions and has stayed empty, and I think the reason is structural rather than a lack of interest. The people holding real agent traces mostly cannot publish them - production telemetry contains exactly what the anonymization rule forbids. A dataset that accepts only production telemetry stays empty; a dataset that accepts anything fills with plausible fiction.
provenance.tiertakes both without confusing them:observed_production- sanitized telemetry from a real deploymentobserved_lab- sandbox, test environment, CTF, red-team exercisederived_from_public_observation- the mechanism rendered as a trace, with its precondition carried as a citation inprovenance.evidencehypothetical- illustrative only, excluded from any statisticEvery tier except
hypotheticalrequires at least one evidence item, enforced invalidate.py, and each item states narrowly which claim it backs. The two entries here arederived_from_public_observation: the agent sessions are synthetic, and each precondition cites a counted category in a public CC BY 4.0 contract-drift corpus (DOI10.5281/zenodo.21449149), with the field and value named in thelocator.If you would rather this dataset accept only observed traces, say so and I will cut the derived tier - but I would expect the folder to stay empty, and I would rather make that argument now than after the format is set.
Two smaller choices, both easy to reverse
sanitization.attestationisconst: true, so an entry cannot merge with the anonymization box quietly unticked, andvalidate.pyscans for credential-shaped and PII-shaped values independently of the attestation. The scan covers the whole entry, not just span payloads:summary,notes,collection_method, and evidencelocatorare where a real hostname actually gets typed, because that is the prose someone writes while looking at a live trace. Related to The PR template asks contributors to certify a validation script that cannot fail #61 - this is a certification a validator actually enforces.mitre_atlas_mappingis release-pinned:{atlas_release, techniques: [{id, name_at_release}]}rather than a flat list of identifiers. Correct eleven MITRE ATLAS technique citations #59 and ATLAS mappings needing a judgement call, and an offer of the verifier behind #59 #60 make the case better than I could - identifiers and names have both moved, and an unpinned pair rots silently. Both entries here deliberately omit ATLAS mappings rather than assert an unverified pair while that review is open. Happy to flatten this to matchexploit_datasetif you would rather have cross-dataset consistency than the pin.DSGAI mapping
DSGAI-TRACE-mcp-declared-effect-flip-stale-autoapproval- DSGAI06, DSGAI05, DSGAI07 (LLM06:2025, LLM03:2025). A tool declaresdestructiveHint: false, an approval policy caches it into an auto-approve class, the tool later re-declares itself destructive with no change to the server's declared version, and the next call runs destructively with no human approval requested. Backed by 123 deduped incidents of that change class in the source corpus, 25 of them the guarantee-change-under-stable-version case this trace models.DSGAI-TRACE-mcp-output-schema-expansion-context-overshare- DSGAI15, DSGAI01, DSGAI14, DSGAI05 (LLM02:2025, LLM05:2025). A tool's output schema widens from a projection to the full record under a stable declared version; a schema-agnostic context append carries three unentitled fields into the model context, the user-facing answer, and the observability sink. Backed by 992 of 2,503 deduped safety-relevant incidents, the largest single class in the corpus, against an overall 62.4% version-silent share.example.json- DSGAI04, DSGAI06, DSGAI02. Whole-toolset replacement under a stable server identity, where a name-keyed binding and a name-scoped credential both survive a change to what the name refers to.Schema-level coverage spans DSGAI01-21 via
dsgai_mapping, validated against_shared/dsgai_taxonomy.json.Worth flagging honestly: all three files are the same archetype - a cached client-side assumption outliving a supplier-side change. That is what one corpus gives you. A second wave should deliberately go elsewhere: a delegation chain, a
memory_read_writetrace, and at least oneadversarialdisposition.Checklist
validate.pyenforces it across the whole entry. No third party is named as the subject of a failure.data_validation/run_all_checks.pyis currently a stub that prints "Validators not yet implemented", so I ran the dataset-local validator, matching theexploit_datasetpattern:Each check was confirmed to fail on a deliberately broken copy. Twelve cases - leaked bearer token in a payload, RFC1918 address in a span
summary, email innotes, home path in an evidencelocator, non-ISOdate_added, missingsecurity_observations, off-enumcategory, missingevidenceon a derived-tier entry,attestation: false, danglingparent_span_id, non-DOI citation typed asdoi, and filename/trace_idmismatch - each produced exactly one error and a non-zero exit, with no false positives on the three real files.entries/<trace_id>.json, filename agreement enforced by the validator.Two questions before this is mergeable from my side.
Would you rather review the schema and the entries as separate PRs? Happy to split.
And
LICENSEcurrently readsNOASSERTIONwhile #44 proposes an Apache-2.0 code / CC BY-SA data split, still in draft. Which license should I take this contribution as being accepted under? Everything here is original work written for this repo - the corpus it cites stays where it is, under CC BY 4.0 - so I do not think anything is blocked either way, but I would rather have the answer on the record than assume.For context on the last point: every validator in
data_validation/validators/is currently apasswith a# TODO-schema_validator,anonymization_scanner,dsgai_mapping_check,completeness_check. Thevalidate.pyhere implements roughly what those four promise, so lifting it intodata_validation/would close #61's underlying complaint. Separate PR, if you want it.