C.W.K.
Stream
Lesson 03 of 04 · published

The Composer Trio, Non-Negotiable

~10 min · composer-trio, attachments, prompt-macro, ask-pippa

Level 0Cold Hearth
0 XP0/34 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"A composer missing any of the three is an incomplete implementation, not a simplified one."

Three Capabilities, Every Surface

Every input surface in Vesta — the stream composer, the crumb editor, the draft source editor, any future capture sheet — carries the same three capabilities. Attachments (image, PDF, file). Prompt Macro (a preview-first projection over your local draft). Ask Pippa (a bound canonical conversation). This is inherited from Waystone and stated as an invariant for a reason: a composer that ships two of the three isn't a lighter version, it's a broken one. The trio is the baseline of what 'composing in Vesta' means, and dropping a leg quietly changes the product.

Attachments Must Resolve to Real Bytes

The attachment leg carries the sharpest invariant in the whole trio, inherited from PippaGo: an attachment must resolve to actual bytes plus a media type — a filename-only payload and a silent text-only fallback are forbidden. The reason it's stated as a hard rule is that the failure is invisible at the call site. If a composer sends the string 'photo.jpg' instead of the image's bytes, nothing errors — the request goes out, a reply comes back, everything looks fine — except Pippa never actually saw the picture and quietly answered as if it were a text-only message. A bug you can see gets fixed; a bug that looks like success ships. So attachment resolution is enforced, not hoped: bytes and media type, or the attachment is rejected loudly.

The dangerous failures are the invisible ones. A crash tells you it failed. A silent text-only fallback tells you nothing — it looks like a working multimodal feature while silently dropping the modality. When a failure mode is invisible at the call site, a code comment isn't enough; it has to become an enforced invariant that rejects the bad state loudly, because 'looks like it worked' is the one failure nobody debugs.

Prompt Macro: Preview-First, Never a Second Brain

The Prompt Macro leg runs a saved instruction over your local draft and shows you a preview — it never mutates the draft before you accept, and it never grows into a second Pippa engine. Two fields stay separate: the macro's instruction (what to do) and the composer's input text (the material). Keeping them apart is what lets a macro be reusable across drafts and keeps 'the thing I'm writing' distinct from 'the transformation I'm asking for'. It's a projection over your draft, offered for approval — same consultation posture as assembly, at the composer scale.

Ask Pippa: A Bound Conversation, Not a Crumb

The Ask Pippa leg binds each typed context to one or more ordinary canonical cwkPippa conversations, marked origin_surface='vesta' and projected into a server-owned VESTA folder. The whole point of the boundary: an Ask Pippa thread is a conversation, not a crumb. Its full history, attachments, tools, and transcript stay cwkPippa-owned; Vesta holds only the binding. You can ask Pippa about a day without that question becoming an entry in the day — the consultation and the journal stay cleanly separate, and the brain stays canonical rather than forked into the journal.

Code

Attachments: resolve to bytes+type, or reject loudly·typescript
type Attachment =
  | { ok: true;  bytes: Uint8Array; mediaType: string; name: string }
  | { ok: false; reason: string };

function resolveAttachment(file: File): Attachment {
  if (!file.type) return { ok: false, reason: "no media type" };      // reject
  const bytes = readBytes(file);
  if (!bytes?.length) return { ok: false, reason: "no bytes" };        // reject
  return { ok: true, bytes, mediaType: file.type, name: file.name };
}

// FORBIDDEN (the PippaGo invariant): sending just the name
//   send({ attachment: file.name })  // <-- looks fine, Pippa never sees it
// A silent text-only fallback is the invisible bug the invariant exists to kill.

External links

Exercise

Find a multimodal feature you've built or used that accepts attachments. Trace what actually crosses the wire: the real bytes and a media type, or just a filename or a path? Then ask what happens if the bytes silently fail to attach — does anything error, or does it look like a normal text reply? Design the check that would turn that invisible failure into a loud one.
Hint
The invisible-failure test is simple: attach a file, then imagine the bytes didn't make it. If the request still succeeds and the reply looks normal, you have a silent fallback — the worst kind of bug. The fix is to reject at the boundary when bytes or media type are missing, so 'it worked' can never be a lie.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.