Skip to content

schema: make inferred a structured field, not a reason-string prefix #131

Description

@blitzcrieg1

Why

Raised in discussion #123 by @mahirhir, who asked whether the inferred: marker survives the ECS and UDM mappings or can be normalized away before an analyst reads the event.

Checked rather than answered from the docs. A synthetic approval_response carrying reason: "inferred:tool_ran_after_prompt" through both adapters:

ECS carries 'inferred:' at: event.reason, agentmetry.action.reason
UDM carries 'inferred:' at: metadata.description

It survives both, so nothing is broken today. But not equally.

The problem

In ECS it lands in two fields, including the namespaced passthrough, and an analyst can filter on it.

In UDM it exists only inside metadata.description, which is free text. Filtering means string-matching a description rather than querying a field, and any normalization step that rewrites or truncates descriptions would drop it with no error.

That is too thin for a marker that a detection rule reads. approval-denied-then-executed skips inferred denials explicitly:

if str(_action(event).get("reason") or "").startswith("inferred:"):
    continue

Ingest synthesises denied responses for asks still pending at session end. Treating those as a human saying no convicted every later call of the same tool and produced twelve criticals on one ordinary Cursor session. So the distinction between observed and inferred is load-bearing, and it currently travels as a substring convention.

Proposal

Add a structured field on the approval, for example action.inferred: bool, or an approval.observed enum if a third state turns out to be needed.

  • Additive to schema 1.2.0. Nothing moves, nothing changes meaning.
  • The inferred: reason prefix stays, so existing consumers and the rule above keep working. It becomes the human-readable half rather than the machine-readable one.
  • ECS maps it to a real boolean field.
  • UDM maps it to a securityResult label or an additional field, not to prose.
  • A test asserting the flag survives both mappings, in a queryable position rather than anywhere in the document. The check I ran for the discussion only asserted the string appears somewhere, which is exactly the weak assertion this issue is about.

Why it matters beyond tidiness

The reason for shipping ECS and UDM at all is that the customer's SIEM is the console. A convention that only works while every reader lives in this repository is not an integration, and "the approval was inferred, not observed" is precisely the field an auditor would ask about first.

Source

Peer review in discussion #123.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions