Skip to content

feat: emit board feature lifecycle events on the workstacean bus (consumer waiting in protoWorkstacean#482) #3549

@mabry1985

Description

@mabry1985

Context

protoWorkstacean#482 tracks a downstream feature blocked on this: when a Linear issue is filed via the Linear → protoMaker board bridge (`LinearProtoMakerBridgePlugin`), the filing close-the-loop is automatic (protoMaker's response routes back as a Linear comment via the existing reply.topic plumbing). What's missing: a "feature done" close-the-loop so that when a board feature is later transitioned to a terminal state, a comment is automatically posted on the originating Linear issue.

This requires protoMaker to publish lifecycle events on the workstacean bus that downstream consumers can subscribe to.

What's needed

A bus event family on the protoMaker side that fires whenever a board feature transitions to a terminal state (done / cancelled / archived). Suggested shape:

```ts
bus.publish("protomaker.feature.completed", {
payload: {
featureId: "...",
projectSlug: "...",
title: "...",
completedAt: ,
transitionedBy: "auto-mode" | "user" | "agent",
// Echo the meta we received on creation (manage_feature dispatches set
// sourceLinearIssueId, sourceLinearIdentifier, etc.) so consumers
// reconstruct lineage without a second query.
sourceMeta: { ... },
},
});
```

For symmetry / completeness, also emit:

  • `protomaker.feature.cancelled`
  • `protomaker.feature.archived` (or whatever terminal states the board supports)

Why on the bus, not via polling

Polling protoMaker for feature state from the consumer side requires the bridge to track every `featureId → linearIssueId` mapping in persisted state, plus a polling loop, plus retry/backoff, plus restart recovery. Pub/sub is the right shape — protoMaker already knows the moment a transition happens.

What lands when this ships

In protoWorkstacean (`lib/plugins/linear-protomaker-bridge.ts`), the done-loop becomes a ~10-line subscriber:

```ts
bus.subscribe("protomaker.feature.completed", "linear-protomaker-bridge", (msg) => {
const linearIssueId = msg.payload?.sourceMeta?.sourceLinearIssueId;
if (!linearIssueId) return;
bus.publish(`linear.reply.${linearIssueId}`, {
payload: { text: `Board feature ${msg.payload.featureId} completed.` },
...
});
});
```

The Linear plugin's existing outbound subscriber posts the comment automatically (and now publishes a `linear.reply.result.${cid}` confirmation event so the bridge knows landing state — see protoLabsAI/protoWorkstacean#486).

Acceptance

  • protoMaker emits `protomaker.feature.completed` on every board state transition into a terminal state
  • Payload includes `sourceMeta` echoed from the original `manage_feature` request meta when present
  • (optional) symmetric `.cancelled` / `.archived` events
  • Once landed, follow-up PR on protoWorkstacean adds the bridge subscriber

Cross-references

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions