Skip to content

Merge run_registrations into runs; make identity columns write-once; stop agents calling create_run #117

Description

@susheem-k

Problem

run_registrations and runs are a 1:1 split keyed by the same run_id, and the
split exists mainly as a workaround: runs is clobberable, run_registrations is not.

  • register_run (control_plane/store.py) writes both: INSERT into
    run_registrations (guarded — RunAlreadyRegisteredError / 409) and create_run
    → REPLACE INTO runs.
  • Every example agent server (entry and downstream: research, summarize,
    writer, analyst, editor, triad *) also calls client.create_run(...) on
    entry (PUT /v1/run-records → REPLACE INTO runs) and client.update_run(...) at
    close.

Result for a 2-agent run sharing one run_id

step writer of the single runs row effect
researcher POST /v1/runs register_run → create_run(agent=intent, dims={user_id:alice}, task=intent) row created
researcher handler client.create_run(agent="researcher", task=<text>, started_at=...) — no dims REPLACE → dims wiped to {}
writer handler client.create_run(agent="writer", parent_span=span_1, started_at=...) REPLACE → agent="writer", started_at=writer clock
writer finally update_run(status=completed, cost_micros, steps=<writer local>) UPDATE
researcher finally update_run(status=completed, cost_micros, steps=<researcher local>) UPDATE (last wins)

Final runs row: agent="writer" (the leaf, not the entry), dims={} — user
attribution lost from runs
(survives only in run_registrations), started_at =
writer's clock, steps = one process's local count. Incoherent, last-writer-wins.

Desired

One runs table:

  • write-once at registration, never in the update path: run_id, intent/task,
    user_dims, mode, parent_run, parent_span, registered_at, started_at.
  • mutable, only via PATCH with an explicit allow-list (update_run already takes
    **fields — enumerate them): status, cost_micros, steps, halt_reason,
    detector, ended_at, governance_events.
  • keep the INSERT-or-409 guard on that one table.
  • remove client.create_run(...) from every agent server. Registration creates the
    row; agents only PATCH. Downstream agents create nothing (they already do not
    register).
  • resolve_run = SELECT ... WHERE run_id=?; "no row" ⇒ not registered (or a
    registered_at IS NOT NULL check).
  • drop create_run from the store protocol / HttpStore (or make it registration-only).

Out of scope

Per-agent participation rows. A single top-level run row is fine — per-agent spend is
already captured in ledger_spent (add an agent-dimension budget/accumulator if a
per-agent breakdown is wanted; segment_key_for already supports dimension="agent").
steps should come from the plane's own step accounting once RunState moves server-side
(plan Part 6), not from a client's local count.

Related: #55, #60, #113, plan Part 6 / Part 9b.

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

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions