CORE DIRECTORY // SYSTEM.USER.DIANA_ISMAIL
Labs by Diana — Experiments that ship.
Side projects that got out of hand. AI tools built for problems I kept tripping over — now live, now yours.
Experiential Brief Generator
MODULE_011
TECHNICAL_OVERVIEW
The tool was built for a specific operational need: a structured brief takes time to produce correctly, and the work of decomposing a client’s ambiguous requirements into a properly structured activation brief is where domain expertise actually lives. The intake agent externalises that decomposition into conversation. It uses tool-use to fill BriefInputSchema field by field across turns, tolerating ambiguity until enough structure exists to hand off to generation - the same way a practitioner would work through a client who does not yet know what they want.
The five-agent generation pipeline uses @diabolicallabs/llm-client ^6.0.0 with the Anthropic provider: the Orchestrator stages the run and distributes inputs; the Concept Generator produces two activation concepts from the brief data; execution pauses at concept_select - an explicit human-in-the-loop gate implemented as a conceptSelectionRegistry Map - where the user approves one concept or requests a regeneration before the pipeline continues; the Vendor Mapper sources relevant suppliers against the approved concept; the Activation Framer builds the execution narrative; the KPI Proposer closes with measurable success criteria. The concept_select gate is load-bearing architecture, not a fallback - it ensures the highest-value creative decision in the brief is made by a person, not resolved automatically.
Attachment handling stores uploaded files as BYTEA in PostgreSQL. The intake agent accepts PDFs (via pdf-parse), images (via sharp), DOCX files (via mammoth), and URLs (via @mozilla/readability with jsdom). URL attachments go through a separate SSRF guard that blocks private IP ranges, written explicitly because the readability fetch path does not sit behind Next.js middleware constraints. All resolved attachments are serialised as base64-encoded LlmContentBlock objects and passed directly to the LLM. Each agent output is Zod-validated against a typed schema with automatic retry on parse failure. The pipeline is live at briefs.diabolicallabs.studio with SSE streaming driving the generation progress surface.
PROJECT_LEARNINGS_LOG
KEY_LEARNING_01
The conceptSelectionRegistry - an in-process Map used to hold the pipeline’s mid-run state across the concept_select pause - is safe for single-instance deployment but will fail silently under horizontal scaling: two Railway instances will not share the same Map, so pause and resume calls can land on different processes. This is a documented architectural seam, not a bug; it was recorded as a technical debt item at the end of week two and must be replaced with Redis pub/sub before any multi-instance deploy.
KEY_LEARNING_02
The SSRF guard on URL attachments had to be written as a separate validation step rather than relying on Next.js middleware, because @mozilla/readability’s fetch path does not sit behind the middleware constraint boundary. The guard blocks private IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16, plus ::1) explicitly - an omission here would leave the URL ingestion path open to internal network access.
KEY_LEARNING_03
The intake agent’s tool-use call can be skipped - the model occasionally answers conversationally rather than calling the tool, particularly on short or ambiguous turns. A fallback extraction pass re-parses the raw assistant message for structured data when no tool call is present in the response. The happy path never exercises this branch, which means it can drift silently without a regression test specifically targeting the no-tool-call scenario.