ResearchOperator Surface

Agent Tag Protocol: Design Exploration

Status: Design exploration for Agent tag protocol (Phase 2, Agent Orchestration Program) — not yet implemented

Problem

Agents produce useful machine-readable signals during their work — "I'm investigating an issue", "I just opened a pull request", "the repo I'm editing is at /workspace/jackin". Today jackin has no way to capture these signals; the operator either reads them in the agent's prose output or doesn't see them at all. As a result, jackin UI cannot show live PR status, can't link the active workspace to its issue, and can't surface the agent's repo-of-record without scraping its stdout.

multicode demonstrates that a tiny opt-in protocol — XML-like tags emitted by the agent and parsed by the orchestrator — is sufficient to turn the agent into an observable workflow node.

Why It Matters

  • It's the cheapest way to make the operator console informative without adding agent-side complexity. Agents emit one line of pseudo-XML; jackin parses, indexes, and renders.
  • It enables the GitHub link tracking feature — without a way for the agent to declare "the issue I'm working" the live-status cache has no input.
  • It is forever once published. Choosing the namespace and vocabulary carefully now is cheaper than re-doing it later.

Inspiration in multicode

Sources:

<multicode:issue>https://github.com/example-org/example/issues/12345</multicode:issue>
<multicode:pr>https://github.com/example-org/example/pull/520</multicode:pr>
<multicode:repo>/workspace/example</multicode:repo>

Skill markdown files (under workspace-skills/) instruct the agent to emit these markers when investigating an issue, opening a PR, or working on a repo. The TUI parser reads the agent's transcript history (SSE events for OpenCode), extracts every <multicode:KIND>VALUE</multicode:KIND> match into the workspace's agent_provided snapshot, and drives icons + GitHub status polling off the captured links.

Important properties: it is skill-driven, not entrypoint-driven — the runtime doesn't enforce emission, roles opt in via the skill the operator includes; idempotent — re-emitting the same tag is a no-op (deduped by value); and optional — agents that don't emit tags work fine, the UI just degrades.

A jackin-namespaced version with a small core vocabulary, an extension point for future kinds, and explicit multi-vendor compatibility (jackin honors <multicode:*> too, so a role designed for either tool keeps working).

Vocabulary (V1)

TagValuePurpose
<jackin:repo>PATH-OR-URL</jackin:repo>absolute path inside container or remote URLDeclares the repo the agent is working on
<jackin:issue>URL</jackin:issue>full GitHub issue URLDeclares the issue under investigation
<jackin:pr>URL</jackin:pr>full GitHub PR URLDeclares the PR being authored or reviewed
<jackin:link>URL</jackin:link>any URLGeneric operator-clickable link
<jackin:status>VALUE</jackin:status>freeform short stringOptional human-readable status override (rendered in the console next to runtime status)

Multi-vendor compat: <multicode:repo> etc. parse identically to the <jackin:*> form. Both populate the same in-memory snapshot. Other vendor namespaces can be added behind a feature flag if/when the ecosystem demands.

Manual repair

Agents will sometimes emit a malformed URL, the wrong issue, or no PR tag at all. Operators need a repair path that fixes the operator surface without rewriting the transcript:

jackin tags set <instance> pr <url>
jackin tags unset <instance> issue <url>

Manual repairs are marked operator-provided, override display state, and stay separate from agent-emitted transcript events. This keeps the console useful even when the protocol is advisory rather than enforced.

Parser placement

The parser sits upstream of the agent runtime status bus — same input stream (the runtime's structured output), different consumer. It emits AgentTagEvent values onto its own channel; downstream consumers (GitHub link tracking, console rendering, persistent storage) subscribe.

The parser must be defensive: tags inside fenced code blocks are ignored (so an agent can document the protocol without triggering it); malformed tags are silently skipped, never errored; a tag value longer than 4 KiB is dropped with a debug log (defends against runaway emission); and extracted URLs are validated (must parse as URL with http(s) scheme, paths must look like absolute paths).

Skill bundles

To make adoption cheap, a small repo of jackin-managed skills would live at jackin-project/jackin-skills (or as a section of jackin-project/jackin-marketplace): jackin-machine-readable-issue instructs the agent to emit <jackin:issue> when investigating, jackin-machine-readable-pr instructs on PR open/review, and jackin-machine-readable-repo instructs on workspace identification. Operators add these to their role's skill list (mechanism per runtime; for Claude, that's the [claude.plugins] array).

Open Questions

  • Multi-vendor extent. Just <multicode:*>, or also <conductor:*>, <sandbox:*>, etc.? Recommended: just multicode for now; add others on demand. The cost of being multi-vendor is tiny but maintaining the list is real.
  • Code-block fencing. Should the parser recognize markdown code fences in the agent's text output, or operate on raw bytes? Recommended: recognize fences for <jackin:*> parsing — operators discussing the protocol shouldn't accidentally trigger it.
  • status tag semantics. Is the agent's <jackin:status> value authoritative, or just a display hint? Recommended: display hint only — the runtime status adapter remains the source of truth.
  • Self-emission for ecosystem skills. Should jackin emit tags on the operator's behalf when, e.g., the operator starts a workspace from a GitHub issue URL? Recommended: yes, eventually. The autonomous queue would emit <jackin:issue> on dispatch.

See Also

On this page