Skip to content

Add @codeassembly/lifecycle with the canonical envelope, vocabulary, and lane fold #1035

Description

@williamthorsen

Problem

The canonical envelope and vocabulary live on the write side (packages/agents/src/emit-event/types.ts), and the only fold from events to lane state is throwaway spike code. The app needs both, and the repo's history shows what hand-copied schemas do: run-log-schema and event-folder drifted into duplicate copies in run-core and factory.

Context

  • The Spike: can skill-emitted events drive a trustworthy live fleet view? #985 findings confirmed the envelope as-is: {id, ts, type, repo, branch, session, cwd, harness, payload}.
  • The emit helper ships as an esbuild bundle inside installed skills, so a workspace dependency on the new library compiles in without changing the installed footprint.
  • Settled lane model: lane = repo × sanitized branch name; sessions are sub-attributions with a harness attribute; lane state is a fold over the lane's event group, never a mutation.

Proposed solution

New package packages/lifecycle. Move the envelope schema and event vocabulary out of agents (which becomes an importer); add the production fold: events → lane state, covering session status derivation (working/waiting from turn.*, work narration from skill.*), session end, lane closure (merge/cleanup events or staleness), and ticket-ref parsing from branch names as a lane attribute — per the shared ticket-id-extraction contract (Jira-style key anywhere in the name, else numeric prefix), extended with .N revisit capture. The pattern contract is defined once here; session-context extraction in agents composes it with its config-dependent formatting. The fold is pure; server-side probes (e.g. worktree existence) feed it as inputs and are not part of this package.

The fold consumes parsed envelopes with caller-supplied lane and session identity; tolerant line and lane-path parsers ship as separate helpers, so file discovery and reading stay with the caller. The package is dependency-free: envelope checking is hand-rolled and tolerant, not a schema library — the envelope is deliberately loose telemetry, so validation would have nothing to reject. All exports are browser-bundle-safe; Node-only helpers, if any, live behind a separate subpath entry.

Acceptance criteria

Must have

  • The envelope schema and vocabulary are defined once, in this package; the emit helper and hook relay import them, and the installed skill footprint is unchanged.
  • The fold derives lane and session state (status, waiting, work narration, closure) from a lane's parsed events; file discovery and reading stay with the caller.
  • A branch name encoding a ticket id — a Jira-style key anywhere in the name, or a numeric prefix, each with an optional .N revisit suffix — yields a ticket-ref lane attribute; other names yield a lane without one. The branch-name pattern contract is defined once, composed by session-context extraction.
  • The package carries no runtime dependencies.
  • The schema and fold entries import cleanly in a browser bundle (no Node builtins).
  • New behavior is covered by tests.

Metadata

Metadata

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions