Record plugin lifecycle and invocation provenance in ATIF exports #32

Closed AtlantisPleb opened this 2d ago 1 comment

Current behavior

/export (openagents.coder.atif_export.v1) captures plugin activity three ways, none typed:

  • The loaded plugin's tool definition rides in agent.tool_definitions (correct, keep).
  • The load act itself — usage errors, manifest_unreadable, and the success line — survives only as free text in extra.notices, with the artifact digest truncated (sha256:7c724f993da2…).
  • The invocation is a normal agent-step tool_calls entry with no plugin provenance.

An ATIF consumer reading steps cannot tell a plugin ran, which plugin, or which exact artifact.

What the spec provides (ATIF v1.7, harbor rfcs/0001-trajectory-format.md)

  • v1.5+: source: "system" steps may carry an observation for "system-initiated operations (e.g., subagent delegation, context management, environment reset, checkpoint creation)". A plugin load is exactly this class — a capability-surface change.
  • ToolCallSchema.extra is designed for per-call metadata ("e.g., timeout, retry count, tool version").
  • ObservationResultSchema.extra for custom result metadata.

Contract

  1. On /plugin load (success or refusal), append a source: "system" step: message is the human notice; observation.results[0] has source_call_id: null and extra typed as {event: "plugin_loaded" | "plugin_load_refused", code?, plugin: {name, version, artifact_digest (full sha256, never truncated), bytes, abi, timeout_ms, capabilities: {mounts: [], hosts: []}, manifest_path, tool_name}}.
  2. Stamp every plugin-backed tool call's tool_calls[].extra with {plugin: {name, version, artifact_digest}} — per-invocation attribution, mirroring the tool.ran thread event and feeding the registry's usage counters from traces as well as threads.
  3. Full digests everywhere machine-read; prose may stay truncated.
  4. extra.notices stays as-is for interface chatter.

Source: docs/plugins/2026-08-24-coder-plugin-demo-shape.md and OpenAgentsInc/openagents.com docs 2026-08-24-registry-network-strategy.md (usage receipts are the registry's substrate).

  1. AtlantisPleb opened this issue 2d ago
  2. A AtlantisPleb Author 2d ago

    Closing as completed. Merged to main and pushed as f65066b3cf (WAL receipt seq 71). Plugin loads and refusals are typed session occurrences (CoderSession.recordPluginEvent, exposed on the snapshot) exported as ATIF source:"system" steps — message is the human notice, observation.results[0].extra carries {event, code?, plugin: {name, version, artifact_digest (full sha256), bytes, abi, timeout_ms, capabilities, manifest_path, tool_name}} — and every plugin-backed tool call exports tool_calls[].extra.plugin = {name, version, artifact_digest}, stamped at entry creation so a mid-session reload cannot rewrite earlier calls' provenance. extra.notices unchanged. 67 targeted tests pass.

  3. closed this as completed 2d ago
Sign in with GitHub to comment on this issue.