Principles¶
How we build backstage-assistants. We work off these principles plus one living diagram document, architecture.md — not a spec or a log of decisions. Change the design, change the document in the same commit.
-
Stitch, don't build. The plugin is glue between well-supported, standards-based, interoperable packages — assistant-ui, the Vercel AI SDK, and Backstage. It is not a framework of its own.
-
Never hand-write what the stack already solves. Conversation and thread management, message history, streaming, tool-calling, persistence adapters — these are solved. Use the library primitive (e.g. assistant-ui's
useRemoteThreadListRuntimeowns thread-list state). If you find yourself writing a store or manager that mirrors a library feature, stop. -
Thin glue only. Glue exists to adapt a package to Backstage — auth,
DatabaseService, config, the Actions registry — and nothing more. Progress is often measured in lines deleted. -
Choose for interoperability and standards. Prefer packages that bolt together through shared standards (AI SDK ⇄ assistant-ui, Backstage core services) and are actively maintained. Pick for "plays nicely," not for the longest feature list. Research the choice before adopting it.
-
The diagrams are the spec. The diagrams and tables in architecture.md are the living source of truth. They must always describe what we are building. No ADRs, no meandering specs to drift out of sync.
-
Delete decisively. Wrong choices and dead code get removed, not worked around or salvaged. A confident document describing code that doesn't exist is worse than no document.
-
The config↔DB seam. Secrets, safety policy, and platform settings live in config — deploy-time, git-controlled, not weakenable at runtime. Editable content and assignment (assistant definitions) live in the DB, managed in-app. Safety gates (approval) and admin membership stay in config precisely because runtime editing must not be able to weaken them.
-
Live source of truth, tolerate drift. Enumerate capabilities live (the registry + MCP
listTools). Validate only new choices; grandfather and surface drift — don't silently drop it or block on it. Don't gate on config that can drift out of sync.