feat(database,service): an agent keeps its automation's name and the run that started it

Merged
DA
3d ago
+10257-23

Summary

Chain F, 1 of 3 (automations batch items 14–17). The stack: F1 keeps the run on the agent, F2 draws the origin message, F3 names automation agents.

  • The agent keeps its automation's name and run. A new nullable coding_agent.automation_origin jsonb column holds the automation's name as it stood, what fired the run, the automation's prompt without the "Luke started this run…" lines, and a webhook's body as its caller sent it, cut at the same character the prompt cut it. automation_id still goes null when the automation is deleted, but the agent still names it (decision 9).
  • Run now records who pressed it. A manual firing now carries the presser's userId, so the agent page can say "Run by …".
  • What the wire carries.
    • An agent's summary gains automationName. F3 uses it as the placeholder title.
    • The agent page gains origin: the prompt alone, the issue or pull request a GitHub event named (subject), the webhook body, and runBy, resolved to the member's current name.
    • Nothing renders any of this yet. F2 draws it.
  • One migration (20261015220902_coding_agent_automation_origin, regenerated on main d73ae2f7): ALTER TABLE "coding_agent" ADD COLUMN IF NOT EXISTS "automation_origin" jsonb, idempotent per the db-migrations skill. That also lets the preview database, which applied this branch's first draft, converge..

Privacy: carve-out D10 lets a webhook body reach the run's agent task, transcript and traces. The body already sits in the agent's task column inside the prompt; the origin stores it a second time on that same row. It is never in a counted event, the runs history, or a summary.

Evidence

  • pnpm check:affected: exit 0, at this stack's tip rebased on main d73ae2f7.
  • pnpm exec vitest run packages/service/src/agents/coding-agents-app.test.ts packages/service/src/automations/ packages/database/src/models/__tests__/: 112 passed.
  • New tests. Each fails on main, where the column and fields don't exist:
    • automation-runs: a run's agent keeps its automation's name, the firing, and the prompt alone, and still names the automation after deleteAutomation.
    • automation-runs: a webhook run's agent keeps the caller's body raw (<, & unescaped) beside the prompt alone.
    • automation-runs: a body cut to fit the task (40,000 <) is kept cut where the task cut it. This is Devin's finding.
    • coding-agents-app: the agent page reads automationName, origin.prompt, the GitHub subject, and runBy for Run now.
  • automations-app.test.ts now expects a Run now firing to carry its presser's userId.

Invariants

  • ./scripts/check.sh green. (CI)
  • JSON Schema goldens changed only under LUKE_UPDATE_FIXTURES=1:
    • coding-agent-wire-codingAgentOriginSchema.json is new.
    • The summary goldens (summary, answer, list answer, and their view twins) gain the optional automationName string.
    • The page goldens (page, page answer, page answer view) gain the optional origin object.
    • These are hosted answers, not model-facing schemas, so no prompt cache is touched.
  • Every behavior change has, in this PR, the test that fails without it; no change-detector test added.
  • Gateway envelope goldens unchanged. (CI)
  • No new as type assertion outside the allowlisted files. (CI via anti-slop)
  • No Effect.runPromise/runSync/runFork outside the runtime edges. (CI)
  • No new raw async primitives. (CI)
  • No discarded Effect, Stream, or Layer. (CI)
  • Test count: +5 (four service tests, one golden).
  • No hand-rolled file replaced.
  • No CLAUDE.md/AGENTS.md sentence names a changed part.
  • PRIVACY.md unchanged.
  • Package deps unchanged.
  • Barrel/door rule unaffected.

Notes

  • Blockers or follow-up verification: none. CI runs on Linux only; this PR has no Mac-specific surface.

🤖 Generated with Claude Code