Skip to content

Add an emit-event skill helper and lifecycle event envelope v0 #986

Description

@williamthorsen

Problem

Interactive skills write artifacts but emit no events, so there is no channel for live lifecycle status (#984). Spike #985 needs a production-track emit helper before skills can be instrumented.

Proposed solution

A bundled skill helper following the derive-session-context pattern: TS at packages/agents/src/emit-event/, a new BundleTarget producing content/skills/emit-event/emit-event.mjs (user-invocable: false), with a smoke test in the existing harness.

Envelope v0: {id, ts, type, repo, branch, session, cwd, harness, payload} — ULID id, nested per-family payload. cwd is included because #984 lists it among the fields (id, timestamp, branch ref, session, cwd) that must align across the lifecycle and KB-curated event stores. Session-lifecycle vocabulary v0: skill.started, skill.progress, skill.completed, artifact.written, input.requested, input.received, pr.created.

Context autofill draws on four sources: repo, branch, and session are each promoted into shared modules under packages/agents/src/shared/ (resolve-repo.ts, branch-helpers.ts, resolve-session.ts) that both capture-event and emit-event consume, rather than either helper duplicating the git-reading and environment-reading logic; cwd comes from the process; harness is not derived at runtime but template-injected at install time, the same way the installer fills capture-event's --harness flag. --session overrides the environment-derived id for the Rovo relay. A single O_APPEND write appends to ~/.codeassembly/events/{owner}/{name}/{sanitized-branch}/{session}.jsonl, with the branch name sanitized the way the branch manifest sanitizes branch names. Never-block contract: any failure warns on stderr and exits 0 — telemetry must not break the skill it observes.

Settled in design review: the payload arrives as --payload '<json>' (a JSON object, default {}); ts is millisecond-precision ISO-8601; an unknown --type warns on stderr but still appends, so the v0 vocabulary is convention rather than a gate; an unresolvable repo, branch, or session falls back to a placeholder path segment (_no-repo/_no-repo, _no-branch, _no-session) instead of dropping the event; the helper always prints a structured {ok, ...} result to stdout. The entrypoint is the skill helper, not an MCP tool (token analysis in comments).

Acceptance criteria

Must have

  • A live Claude session appends valid envelopes with nothing supplied beyond --type and payload.
  • --session overrides the environment-derived session id.
  • Any emission failure warns on stderr and exits 0.
  • An event with an unresolvable repo, branch, or session is appended under placeholder path segments rather than dropped.
  • An unknown --type warns on stderr and the envelope is still appended.
  • New behavior is covered by unit tests; the bundle has a smoke test.

Part of spike #985 (blocks its observation window).

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