05. Developer Journal

This section documents the real problems encountered, how the architecture evolved over time, and the specific solutions that fixed production-breaking issues. These aren't theoretical challenges—these are the hard-earned lessons that transformed a fragile script into a robust OS.
The Road to Production: Architectural Evolution
Our system didn't start as a 74-node behemoth. It evolved through painful lessons and necessary pivots.
v1: The Naive Approach (Twitter-Only, Manual)
- Architecture: Simple Telegram bot connected to Twitter API.
- Limitation: No AI. Required manual formatting of every tweet.
- Outcome: Achieved 60% engagement, but didn't save time because the manual labor of adapting technical notes to threads remained.
v2: Introduction of AI
- Architecture: Added Gemini to process raw text.
- Limitation: Basic prompts led to generic, "AI-sounding" output that damaged authenticity. Still Twitter-only.
- Outcome: Engagement rose to 70%, but the "Capability-Compliance Gap" (where the LLM ignores formatting rules in favor of prose) started breaking the pipeline.
v3: The Monolith (Multi-Platform)
- Architecture: One massive 50+ node workflow attempting to extract, generate, and post to Twitter, LinkedIn, and the Blog simultaneously.
- Limitation: Unmaintainable spaghetti logic. A timeout on the Blog API would crash the entire workflow, preventing the Twitter and LinkedIn posts from executing.
- Outcome: A 15% failure rate in production. We realized monolithic design is a death sentence for API-heavy automations.
v4: Bi-Part Separation & Session Management
- Architecture: Split the workflow into Part 1 (Generation) and Part 2 (Distribution) with a Human-in-the-Loop review gate.
- Limitation: Concurrent execution caused file cross-contamination in Google Drive (images for Post A attached to Post B).
- Outcome: Implemented the Hybrid Session ID System (
session_${Date.now()}_${id}). Reached 99.7% reliability.
v5.0: The OmniPost OS (Current)
- Architecture: Integrated Obsidian MCP for localized brain context, Tavily for live research, and the Decision Engine V5.0.
- Outcome: Full-scale Agency Automation OS. Zero-cost operations.
Challenge 1: Multi-Platform Asset Management
The Problem I Faced Each platform has different image handling capabilities:
- LinkedIn: Initially appeared restricted to 1 image (API limitation via default n8n node)
- Twitter: Specific upload endpoints required (OAuth 1.1 vs 2.0)
- Blog: Unlimited images but require distinct Markdown/HTML structure
The AI generates content with image markers (<<IMAGE_1>>, <<IMAGE_2>>), but images might not exist yet, and missing images shouldn't break the workflow.
Initially, trying to force multi-image posts on LinkedIn caused silent API failures.
My Solution: Hierarchical Decision Engine + S-Tier HTTP Pipeline
I built a three-tier decision system (Code – Detect Images Needed vs Present):
- Tier 1: Trust AI-generated markers (highest priority).
- Tier 2: Fallback to manifest (Image Tasklist) if markers are missing.
- Tier 3: Default to no images if no evidence, removing
<<IMAGE_N>>placeholders gracefully.
Evolution: I completely bypassed the LinkedIn default node limitation by constructing an S-Tier HTTP Pipeline (Init Upload → Binary Upload → Post), enabling robust multi-image and PDF carousel support.
Result: Flawless multi-asset routing across all platforms, transforming basic image handling into a professional-grade distribution engine.
Challenge 2: Markdown-to-Platform Conversion
The Problem I Faced
Unified markdown doesn't work for all platforms. Twitter needs 4 separate tweets (280 chars) threaded together. LinkedIn needs single posts with \n\n paragraphs. Blog needs Portable Text blocks.
Initially, simple string splitting posted tweets out of order and attached images incorrectly.
My Solution: Platform-Specific Parsers
Created dedicated parsing logic for each platform. Twitter iterates over tweet blocks and maintains an inReplyTo boolean for threads. LinkedIn extracts only the first image and strips ALL markdown. Sanity CMS converts markdown to Portable text objects where images are referenced by _ref IDs.
Challenge 3: Session-Based File Management
The Problem I Faced Multiple content pieces processing simultaneously resulted in a file organization nightmare. Files mixed together, causing a 15% failure rate and requiring manual cleanup.
My Solution: Hybrid Session ID System
Generated a unique sessionId (session_${Date.now()}_${notionId.substring(0, 8)}) for every content piece. All files (twitter_draft_..., asset-1-...) include this ID. In Part 2, the Organize Assets node explicitly filters files:
Result: Zero cross-contamination in 1000+ executions.
Challenge 4: Error Handling & Reliability
The Problem I Faced 46 nodes × 5 APIs = hundreds of potential failure points (timeouts, rate limits, missing data).
My Solution: Multi-Layer Handling
- Node-Level:
retryOnFail: true,maxTries: 3. - Graceful Degradation: If an optional manifest parse fails, assume no images and proceed.
- Fail-Fast: Throw hard
FATALerrors ifFolder IDcannot be extracted. - Partial Success: Track results individually. If Twitter and LinkedIn succeed but Blog fails, update Notion Status to
Partially Posted.
Session Insights (from Obsidian Second Brain)
Insight A: "Capability-Compliance Gap" & Image Markers
Date: 2026-03-17
Issue: Claude Sonnet 4.5 dropped <<IMAGE_X>> markers in 4 out of 5 prompts. The hypothesis that the proxy was stripping markers was disproven because LinkedIn retained them.
Root Cause: "Capability-Compliance Gap". Sophisticated models (Claude) deprioritize simple mechanical tasks when competing with complex creative rules in 300+ line prompts.
Fix: Implemented the 6-Point Reinforcement Pattern. Any mandatory mechanical requirement must appear in: (1) Think tool pre-planning, (2) Simplified rules, (3) Pre-output verification, (4) Output JSON example, (5) Validation checklist, and (6) Final instruction at the absolute end.
Insight B: Repo Split and IP Protection
Date: 2026-03-29
Issue: Sharing the build-in-public journey risked exposing proprietary B2B IP (JSON workflows, prompts, code nodes).
Decision: Separated proprietary execution logic into the private OmniPost-Core repo. Enforced an "S-Tier" CLAUDE.md / GEMINI.md with automated Pre-Push security gates (git diff --cached scans for keys, .env files, and proprietary code). Public portfolio (amansuryavanshi.dev) serves strictly as the architecture/PRD showcase; the private repo holds all execution-layer code.
Insight C: Part-1 Timeout & Threads Lane
Date: 2026-04-09
Issue: Part-1 generation hit a 300s timeout due to slow cross-node data lookups ($('<Node>')) inside the Code – Personal Context Builder.
Fix:
- Switched Merge Node to Append mode so all 3 inputs (Obsidian Overlay, Standardized Context, Content) hit the Code node natively via
$input.all(). - Disallowed
JSON.stringifyon massive payload objects, mandating safe parsing of ONLYoutput[0].content[0].text. - Threads integration locked as a first-class lane matching Twitter/LinkedIn (IF → Prep Code → HTTP), utilizing
THREADS_USER_IDfrom env and enforcing the 30-second container wait time.
Insight D: The 2000-Character Notion Limit & Chunking
Date: 2026-04-29
Issue: We originally stored markdown drafts in Google Drive to avoid Notion's strict 2000-character limit per rich text block. However, editing and approving markdown files in Google Drive proved to be a messy, high-friction user experience.
Root Cause: Notion's API violently rejects any rich text array object where the text.content string exceeds 2000 characters.
Fix: We migrated draft storage completely to Notion to enable seamless inline editing. To bypass the API limit, we implemented a semantic chunking utility in the Code-Prep nodes of Part 1. This function splits massive AI-generated drafts into multiple <2000 character string segments, maps them into an array of valid Notion rich text objects, and injects them directly into the Notion Social Content Queue. Google Drive is now strictly reserved for uploading the visual asset-X media files.
Insight E: Why Image Generation Stays Manual
Date: 2026-04-29
Issue: Image generation can be automated via API (Imagen, DALL-E, Flux), but each call costs credits and the output quality is inconsistent for brand-specific assets like architecture diagrams and infographics.
Decision: We deliberately keep image generation as the one manual step in the pipeline. The local AI coding environment (Antigravity) has full access to brand design skills, draw.io/Excalidraw architect skills, and rich project context — enabling high-fidelity, on-brand asset creation at zero cost. The AI generates an Image Tasklist describing exactly what visuals are needed; the human generates them locally, names them asset-1, asset-2, etc., and drops them into the Google Drive session folder.
Future: If API image generation costs drop or quality reaches brand-consistency thresholds, this step can be automated by wiring an image generation node into Part 1 after the platform writers.