Skip to content

Sketch: Shuttle.WorkSource behaviour for non-felt adapters #1

@cailmdaley

Description

@cailmdaley

The idea

Shuttle currently couples to felt entirely through the felt CLI (felt ls --json, felt show -j, felt edit, felt history append). This coupling is clean — at the I/O boundary, no in-process parsing — but it's also singular. A Shuttle.WorkSource behaviour would let other work sources (Linear, GitHub Issues, etc.) plug in without forking the engine.

Seams (from analysis)

The coupling is concentrated in two places in the Elixir engine:

  1. Reads via feltShuttle.Poller walks each configured felt host's .felt/ for ownership but pulls candidate metadata via felt ls --json and per-fiber detail via felt show -j. These are the only read paths.
  2. Writes via felt and shuttle-ctl — Worker scripts and the agent API invoke felt show, felt edit, felt history append. shuttle-ctl's YAML AST writer (pkg/schema/io.go) is the only frontmatter writer in shuttle, and it owns the shuttle: block specifically.

Both seams are at the I/O boundary, so a Shuttle.WorkSource behaviour is feasible — but it is not free. The Poller's eligibility predicate, the Dispatcher's prompt composition, and the felt-native status:/tempered:/outcome: fields are all deeply felt-shaped. An abstraction that paper-covers those would be thinner than it looks.

Scope for this issue

This is a sketch, not a worked design. The right next step is:

  1. Enumerate the minimal callback set a work source needs to implement (list eligible items, fetch item detail, write status/outcome, append history event).
  2. Identify what's felt-specific vs what's work-source-generic in the Poller and Dispatcher.
  3. Decide whether the abstraction should live at the Poller level, the Dispatcher level, or both.

The v0 publication ships with felt as the only adapter. This issue tracks the idea so it doesn't get lost.

Reference

The detailed coupling analysis is in the felt-coupling-seams fiber (internal). The key finding: both read and write seams are at the CLI/process boundary, which is the right layer for an abstraction.

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