Skip to content

spec_change: agent_id as the correlation key for OCSF ai_agent.instance_uid (§3.1, §5.2) - #270

Open
rabbidave wants to merge 3 commits into
agentrust-io:mainfrom
rabbidave:agent-state-correlation-key
Open

spec_change: agent_id as the correlation key for OCSF ai_agent.instance_uid (§3.1, §5.2)#270
rabbidave wants to merge 3 commits into
agentrust-io:mainfrom
rabbidave:agent-state-correlation-key

Conversation

@rabbidave

Copy link
Copy Markdown

Closes #269. Companion to the non-normative pointer in #268 (that one is deliberately untouched by this PR).

What this changes:

  • §3.1: makes explicit and normative what §5.3.1 item 3 already implies for gateways (agent_id == "the authenticated workload subject for the current session") — extended here to OCSF-emitting runtime-evidence producers. When such a producer emits an ai_agent-bearing event for a manifest-governed session, ai_agent.instance_uid MUST equal this manifest's agent_id.
  • §5.2: adds optional runtime_correlation_key to the verification result, echoing agent_id so a runtime-evidence consumer doesn't need to re-parse the manifest for the join key. fields_verified is untouched — stays boot-time-only per §7.2.
  • CHANGELOG: [Unreleased] / Added entry per repo convention.

Why instance_uid and not version/charter: both are static across a session (agent code/config revision, durable role doc) — not usable as a per-event join key. They stay useful as secondary context once an instance is already identified.

Worked example (§5.2) uses real output from rabbidave/ws4-secure-design-agentic-systems@1e35ab5: AgentIdentity now feeds OCSF's actual ai_agent object (uid/instance_uid/version/charter/token_fingerprint) instead of the flat, model-conflated agent_uid that implementation used before this fix. The OCSF event block in the example is unmodified output from that code, not hand-authored.

Known open question, not resolved here: agent_id is asked to serve both OCSF's uid (stable) and instance_uid (session-scoped) concepts. §3.1 notes a future revision may split this into two fields if the overload proves to be a problem; this PR doesn't propose that split, flagging it for reviewers instead.

cc @imran-siddique

…ce_uid

Section 5.3.1 already binds agent_id to "the authenticated workload
subject for the current session" for gateway runtime-session binding.
This makes the same binding explicit and normative for OCSF-emitting
runtime-evidence producers: when such a producer emits an ai_agent-
bearing event (e.g. Agent Inventory Info [5050]) for a manifest-governed
session, ai_agent.instance_uid MUST equal this manifest's agent_id.

Verification results gain an optional runtime_correlation_key field
(section 5.2) that echoes agent_id back, so a runtime-evidence consumer
doesn't need to re-parse the manifest to get the join key. fields_verified
is untouched -- it stays boot-time-only per section 7.2; this does not
make the manifest a runtime monitor.

Worked example uses real output from the reference implementation
(rabbidave/ws4-secure-design-agentic-systems@1e35ab5): AgentIdentity now
feeds a proper OCSF ai_agent object (uid/instance_uid/version/charter/
token_fingerprint) instead of the flat, model-conflated agent_uid that
implementation used before.

Does not split agent_id into separate stable/instance fields -- flagged
as an open question for reviewers rather than decided here.

Closes agentrust-io#269.

@imran-siddique imran-siddique left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed this properly against the OCSF schema rather than on the description alone. The problem you identified is real and worth fixing: there is no defined join key between a manifest and OCSF runtime evidence, and picking one is overdue. Your reasoning for choosing instance_uid over version and charter is right, both are static across a session and useless as per-event join keys. Keeping fields_verified boot-time-only per section 7.2 is also correct.

Three things block it as written.

1. The MUST contradicts what OCSF says the field is. From objects/ai_agent.json in ocsf-schema main:

  • uid: "The stable logical identifier for the agent, assigned by the agent's authoritative source"
  • instance_uid: "Identifier for a specific running instance or session of the agent, distinct from the stable logical uid. An instance is a single materialization of the agent."

OCSF makes the distinctness explicit. Section 3.1 immediately above your addition says the /agent/<name>/<instance> path structure is "a convention, not a requirement", so a conformant agent_id may legitimately be stable and carry no instance scope at all. In that configuration your MUST forces a stable identifier into a field OCSF defines as the non-stable one, and the worked example populates uid, instance_uid and session_uid with the same string, which erases the distinction OCSF created the field to express. A consumer can then no longer separate "every run of payments-processor" from "this run".

You flag the overload as a known open question and defer the split. That is the reason not to freeze it as MUST now: if a later revision splits the field, it breaks a normative requirement rather than refining an informative one.

2. The carrier class does not exist in OCSF. Agent Inventory Info [5050] is not in ocsf-schema main. There is no agent_inventory_info.json under events/discovery/, and no occurrence of 5050 anywhere in the repository. The ai_agent object is real, the class you cite as carrying it is not, at least not in core OCSF. If it comes from an extension, say which, because normative text in this spec cannot depend on an event class that core OCSF has not assigned.

3. runtime_correlation_key should be dropped. It is a verbatim copy of agent_id, defined as always present, and explicitly does not affect result or fields_verified. The consumer that reads it has just verified the manifest, so it already holds agent_id. That is zero information gain inside a signed structure, and it introduces a failure mode that does not otherwise exist: two signed copies of the same identity that an implementation can make disagree. The sentence "A verifier that has no runtime-evidence consumers MAY omit populating downstream consumption of this field, but the field itself is always present" is also not usable as normative text, since it permits and forbids in one breath.

On sourcing. The worked example and the reference implementation are both rabbidave/ws4-secure-design-agentic-systems@1e35ab5. One personal implementation is not enough to anchor a MUST that binds every OCSF-emitting producer.

What would land. Either of these works:

  • Make it informative. A crosswalk section stating that where a producer emits ai_agent for a manifest-governed session, instance_uid is the intended join key, with uid carrying the stable manifest-level identity. That is close to the non-normative pointer in #268 and needs none of the above resolved.
  • Keep it normative but scope it to a profile that declares OCSF emission in scope, and resolve stable versus instance first: bind ai_agent.uid to the stable identity and instance_uid to the session-scoped value, which is what OCSF's own definitions ask for. That likely does need the agent_id split you deferred.

Worth raising in the CoSAI WS4 stream either way, since section 3.1 already defers the canonical @context URL to WS4, and an OCSF correlation mapping belongs in the same venue rather than being settled here first.

imran-siddique added a commit that referenced this pull request Aug 4, 2026
Mirrors agentrust-io/trace-spec#120. The rule that normative spec changes
need an organizational sponsor is applied in review but written down
nowhere, so contributors meet it for the first time on their own PR,
after doing the work. #270 is a live example: a normative MUST binding
agent_id to OCSF ai_agent.instance_uid, authored individually, where the
authorship question only surfaced at review.

No change in practice. It also writes down that anyone may propose a
normative change, that proposals are judged on the argument alone, and
that a Maintainer carries the PR when an accepted proposal has no
sponsor, all of which was already true and equally unwritten.

Calls out explicitly that informative crosswalks and mappings to external
schemas need no sponsor, since that is the path a proposal like #270 can
take today.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@imran-siddique

Copy link
Copy Markdown
Contributor

Heads up that the branch now conflicts with main, so a rebase will be part of whichever direction you take. No rush on my end, and the review above still stands as written.

@rabbidave

Copy link
Copy Markdown
Author

@imran-siddique Taking the informative path. Your three points hold, and I
checked ocsf-schema main rather than argue from the descriptions.

  1. instance_uid. Worse than your review said, in two ways. Main's description
    states an instance may persist across restarts and may span multiple
    cooperating runtime components, so several events can share one instance_uid.
    It is conversation-or-session scoped by definition, which rules out the
    per-emission reading my text depended on. And session_uid is not in the
    dictionary at all, on ai_agent or anywhere in its 963 attributes, so the
    worked example was populating a field I had invented locally. That is on me.

  2. Agent Inventory Info [5050]. Confirmed unassigned. Discovery runs to Cloud
    Resources Inventory Info [5023] plus Live Evidence Info [5040], and no agent
    inventory class exists on main under any name I probed. I should not have
    cited it. I have opened Discovery: agent trust-base inventory, applying record_integrity per emission ocsf/ocsf-schema#1724 upstream proposing the class properly,
    targeting 1.10. Until a class_uid is assigned there is nothing here for
    normative text to bind to.

  3. runtime_correlation_key. Dropping it, and the better argument against it is
    that OCSF already solved what it was reaching for. The record_integrity
    profile on main carries an attestation object with chain_uid, prev_event and
    authority_uid, which gives per-emission integrity and chain membership
    without a second copy of the identity inside a signed structure.

Reworking this as the crosswalk you described: where a producer emits ai_agent
for a manifest-governed session, instance_uid is the intended join key and uid
carries stable manifest-level identity. No RFC 2119 keywords, no dependency on
an unassigned class. That collapses it into the shape of #268 rather than #269.
Rebasing onto main as part of the rework.

Separately on the sponsor rule from #269. I am planning to sponsor the normative
version on PayPal's behalf, pending sign-off from our execs and legal. That is
not a request to hold anything: the crosswalk above should land on its own merits
now, and if sponsorship clears I would pick the normative piece back up as a
sponsored change rather than leaving it maintainer-carried. Flagging it early
because the CHARTER §4 IPR point you raised is exactly what our counsel will look
at, so your note there is useful to me rather than an obstacle.

One thing for the trust-anchor thread rather than this one: attestation.
authority_uid on main is described as letting a verifier confirm a signing
credential belongs to the expected authority rather than to a different holder of
some otherwise-valid credential, which is close to what @litzki-systems is asking
for in cosai-oasis/ws4-secure-design-agentic-systems#149. Raising it there, not
here. @Levaj2000 is carrying the related stop_reason work in
ocsf/ocsf-schema#1704.

@imran-siddique

Copy link
Copy Markdown
Contributor

Yes, the crosswalk is the shape I want, and it can land on its own merits now. No RFC 2119 keywords and no dependency on an unassigned class is exactly right: a join key documented as intent is useful to implementers today, and it does not commit the spec to a reading of instance_uid that OCSF main does not support.

Your reading of instance_uid is better than mine was. Persisting across restarts and spanning cooperating components rules out per-emission joins entirely, which is worth saying plainly in the crosswalk text so nobody rediscovers it. Dropping runtime_correlation_key in favour of the record_integrity attestation object is the right call for the same reason.

Thanks for opening ocsf-schema#1724 rather than citing a class that does not exist. That is the correct order.

On sponsorship: useful to know, and no pressure either way. If it clears, a sponsored normative change is better than a maintainer-carried one and I would rather wait for it than carry a MUST that your counsel has not seen. If it does not clear, the crosswalk still stands on its own.

Take your time on the rework. Whenever you push it, rebase onto main first, CHANGELOG.md and the spec file both conflict again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

spec_change: designate agent_id as the correlation key for OCSF ai_agent.instance_uid (§3.1, §5.2)

2 participants