# Pipeline Test Report — PayWise 2026-09_SEP **Date:** July 27, 2026 **Test type:** Full 5-stage manual pipeline via `opencode run` **Verified against skills:** `content-plan-generator`, `carousel-prompt-generator`, `blog-post-generator`, `infographic-brief-generator`, `monthly-drop-landing-page` **Result:** All stages passed. Landing page live at https://paywise-monthly-drops.vercel.app --- ## 1. What the Test Proved ### Core findings - The `[AUTO-MODE]` header + comprehensive pre-answered prompt **works for all 5 skills** — zero interactive questions asked. The key insight: skills aren't asking questions because they're broken — they're asking because they're designed to be thorough. Pre-answer everything. - Each `opencode run` is an **isolated session** — downstream stages cannot reference prior session state. Every prompt must be fully self-contained. You cannot do "generate .md" then "generate .html" in two separate calls. - Skills load their sub-skills automatically (content-strategy, copy-editing, copywriting, seo-audit, ai-seo, image, marketing-psychology, brainstorming) — no need to specify these. - The "generate .html immediately, do NOT ask for approval" instruction reliably bypasses the HTML approval gate — but it must be in the **same prompt** that generates the .md, because a second call has zero context. ### Timeout lessons - A 5-minute timeout is **too short** when a skill enters an interactive waiting state (blocked on stdin). The process doesn't error — it just sits there consuming time. - The timeout parameter is a `bash` tool concern, not intrinsic to `opencode run`. Running directly from a terminal has no timeout at all. - 15 minutes per stage is a safe programmatic timeout. Actual content generation completes in ~5 min; the landing page stage (with npm install + build + Vercel deploy) takes ~8 min. - The actual failure mode of a timeout is subtle: the shell kills the process, which may leave **partial output files** on disk. This happened during testing — two .md files were created but the process was killed before the .html could be generated. The partial output can mislead you into thinking the skill completed. ## 2. Testing Narrative — The Full Story This section walks through the testing sessions chronologically, explaining what happened, why it happened, and what we learned at each step. --- ### Chapter 1: Setup — The Foundation Work Before the first `opencode run` could be attempted, several structural issues had to be resolved: 1. **CYCLE_CONTEXT.md regeneration** — The existing cycle folders referenced stale paths (`_knowledgebase/`, `BrandKit/`). These had been consolidated into `01_knowledge_base/`, `02_brand_kit/`. Every existing CYCLE_CONTEXT.md had to be rewritten. 2. **Brand guide corruption** — `PayWise_brand_guide.md` had a null byte injected somewhere, which broke file reads. Had to clean and re-save. 3. **SKILL.md path fixes** — 5 skills had hardcoded or outdated references to folder paths. Content-plan-generator was patched for dual-path brand guide lookup. Carousel-prompt-generator, blog-post-generator had knowledgebase path fixes. All 5 were synced to `~\.agents\skills\`. 4. **New cycle folder** — 2026-09_SEP didn't exist yet. Created with 7 subfolders and a minimal CYCLE_CONTEXT.md (with a note that direction needed manager input). 5. **product-marketing.md generation** — The `.agents/product-marketing.md` didn't exist for PayWise. Had to generate it from the SOP template (7 sections, 5,951 bytes of brand context). 6. **`run_monthly_cycle.ps1` stale paths** — Referenced `Monthly_Cycles\` instead of `03_monthly_cycles\`. Fixed. This phase felt productive but was time-consuming. The critical realization: the skills assume a certain folder structure and file convention, and any deviation causes them to either fail silently or ask unnecessary questions. **The 7-index folder structure must be exactly right for every cycle, every time.** --- ### Chapter 2: The First `opencode run` — "Why is it timing out?" The initial plan seemed straightforward: run `opencode run` with the short prompt from `run_monthly_cycle.ps1`: ``` Generate the content plan for PayWise, cycle 2026-09_SEP. Proceed automatically... ``` We ran it with a 5-minute timeout. The process started, loaded the skill, and... sat there. **5 minutes later:** timeout. No output files. The skill had loaded but was waiting for interactive input — it needed to ask about language, direction, deliverables, and approval gates. The `[AUTO-MODE]` header wasn't in the prompt. The "proceed automatically" instruction was too vague. **Mistake:** We assumed "proceed automatically" was a magic phrase. It isn't. Skills process instructions literally. If you don't specify the language, the skill asks. If you don't specify the deliverables, the skill asks. If you don't specify the direction, the skill asks. The script's short prompts were designed for interactive use, not headless automation. --- ### Chapter 3: The Second Attempt — "Wait, there's output?" We increased the timeout to 15 minutes and expanded the prompt slightly. This time the process ran the full duration. But the output was never captured — the process was interrupted before the `opencode run` result could be read back. **Then we checked the output directory:** Two files existed. ``` 01_content_plan/output/ ├── PayWise_Content_Plan_SEPTEMBER_2026.md (42,351 bytes) └── PayWise_Content_Plan_SEP_2026.md (34,361 bytes) ``` Two .md files. No .html files. The skill had been mid-execution when killed — it had written the .md content plan but hadn't gotten to the .html step. The timestamps told the story: - 6:41 PM — first .md created - 6:47 PM — second .md created (6 minutes later, likely a retry or continuation) - The process was killed shortly after **Critical discovery:** `opencode run` is one-shot. When we killed and retried, the new session had **zero memory** of the previous session's work. The second .md file was a fresh attempt at the entire content plan, not a continuation. **No session persistence between invocations.** The two .md files were different sizes (42KB vs 34KB) because different variations of the prompt caused different output. One used "SEPTEMBER", the other used "SEP" — a consequence of slightly different prompt wording. --- ### Chapter 4: The Eureka Moment — "Pre-answer EVERYTHING" At this point the pattern was clear: the skills are thorough, and they need explicit instructions for every choice they'd otherwise ask about. The solution was to write a **comprehensive prompt** that pre-answers every possible question: - `[AUTO-MODE]` header to suppress interactive behavior - Brand name, language, brand directory path - Strategic direction (1-3 lines of actual strategy, not "proceed") - Exact deliverable breakdown (8 carousels, 4 blogs, 4 newsletters, 2 infographics) - Output path - Explicit "generate .md then .html immediately, do NOT ask for approval" **Third attempt (Stage 1 — Content Plan):** ```powershell opencode run "[AUTO-MODE] Use the content-plan-generator skill for PayWise... Direction: Post-90-day roadmap maintenance. Keep activation focus... Deliverables: Carousels: 8, Blog posts: 4, Newsletters: 4, Infographics: 2... IMPORTANT: Generate .md then .html immediately. Do NOT ask for approval..." ``` **Result:** Ran cleanly in ~5 minutes. Both .md and .html generated. The skill loaded its sub-skills (content-strategy, copy-editing), updated the editorial note, ran the Seven Sweeps polish, and produced a 30-deliverable content plan with 96KB styled HTML. The HTML was impressive — dark/light toggle, search, filter by type/persona, copy-to-clipboard, scroll-spy navigation. All inline, no external dependencies. **Lesson crystallized:** The difference between "doesn't work" and "works perfectly" is the level of detail in the prompt. The skills are capable — they just need to be told everything upfront. --- ### Chapter 5: Running the Rest — "It just works now" With the comprehensive prompt pattern established, Stages 2-5 were run sequentially. Each took a single `opencode run` with the same structure: `[AUTO-MODE]`, skill name, content plan path, brand guide path, output path, and "do NOT ask for approval." **Stage 2 — Carousel Prompts:** - Result: 8 carousels, 27 slides - Two files: 60KB .md + 86KB .html - Loaded image skill + marketing-psychology for psychological hooks - Applied PayWise Prompt Improvement Guide rules (CBTT mentions capped at 2, type-first layout, documentary photography style) - Ran cleanly in ~3 minutes **Stage 3 — Blog Posts:** - Result: 4 blog posts (Week 1-4) - Loaded brainstorming, copywriting, seo-audit, ai-seo skills - Scanned knowledgebase for claims sourcing - Couldn't find sitemap (doesn't exist) — used `paywise.co` URLs inferred from content plan - Ran in ~5 minutes **Stage 4 — Infographic Briefs:** - Result: 2 infographic design briefs - October Bill Calendar (1080×1920 portrait) + PayWise September Highlights (1080×1080 square) - Fastest stage — completed in ~2 minutes - Each brief included dimensions, color palette, layout specs, visual hierarchy **Stage 5 — Landing Page:** - Result: Full TanStack Start React application - Created paywise-content.ts with all 30 items, 8 carousels, 4 blogs, 4 newsletters - Ran npm install (380 packages), npx vite build (client + SSR) - Generated 43 placeholder images (1×1 pixel PNGs) for all carousel slides, blog banners, newsletter covers - Copied content-plan.html and blog-posts.html to public/ - Initialized git, committed (119 files, 16,228 insertions) - Force-pushed to github.com/deigo-PC/paywise-monthly-drops - Took ~8 minutes total (longest stage) At this point all 5 stages had passed. But there was one more surprise waiting. --- ### Chapter 6: The Vercel Twist — "Wrong project!" The landing page skill attempted Vercel deployment at the end of Stage 5. It: 1. Checked `gh auth status` — logged in ✅ 2. Tried `gh repo create paywise-monthly-drops` — failed (already existed from a previous test session) 3. Added the remote and force-pushed ✅ 4. Checked for `vercel` CLI — not installed ⛔ 5. Tried `webfetch` to check if the domain was live — domain didn't respond The skill couldn't deploy because the Vercel CLI wasn't on the system. So we installed it: ```powershell npm install -g vercel ``` Then ran `vercel --prod --yes` from the landing page output directory. It built successfully, deployed successfully, but created a **new project** called `deigo123/output` instead of deploying under the existing `paywise-monthly-drops` project. The `.vercel/project.json` had `"projectName": "output"`. The fix: ```powershell vercel link --project paywise-monthly-drops --yes vercel --prod --yes ``` The second deploy aliased to https://paywise-monthly-drops.vercel.app — and worked. **Lesson:** The `vercel.json` is in the template, but Vercel project linking isn't idempotent. First-time deploy from a fresh clone creates whatever project name Vercel infers. The script needs to explicitly link to the existing project before deploying. --- ### Chapter 7: Final State The landing page loaded correctly at https://paywise-monthly-drops.vercel.app — showing Instagram grid preview, 8 carousels with slide-by-slide navigation, 4 blog posts with "Read full post" links, 4 newsletter previews with copy-to-clipboard, and Content Plan / Marketing Hub buttons. All 30 deliverables from the content plan were represented on the landing page. Every reference was branded: "Licensed by the Central Bank of Trinidad and Tobago" on every carousel and blog post. The full pipeline — from empty cycle folder to deployed landing page — ran in approximately **25 minutes of cumulative processing time** across 5 `opencode run` invocations, plus ~10 minutes of setup and ~10 minutes of Vercel troubleshooting. --- ### What it felt like The process was a sequence of small mysteries, each resolved by understanding what the skills actually needed: 1. **"Why is it waiting?"** → The skill needs to ask questions. Pre-answer them. 2. **"Why does the second call not know what the first call did?"** → `opencode run` is strictly stateless. Every call is a clean room. 3. **"Why two .md files?"** → Each `opencode run` is independent. One created a file, the other created a different file. Not a continuation. 4. **"Why no .html?"** → The .html generation is behind an approval gate. You must say "generate .html immediately" in the SAME prompt. 5. **"Why did Vercel create 'output' instead of 'paywise-monthly-drops'?"** → First deploy from a new directory auto-creates a project. Must `vercel link` to existing project first. None of these were bugs in the skills or tools. They were all gaps between the script's assumptions and how `opencode run` actually behaves. The skills themselves are well-designed — they're thorough, they load relevant sub-skills, they produce high-quality output. They just need to be told everything upfront because they can't ask follow-ups in a non-interactive context. ### Bugs Found in `run_monthly_cycle.ps1` | Line | Current | Should be | |------|---------|-----------| | 72 | `03_infographic_briefs\` | `04_infographic_briefs\` (wrong folder index) | | 79, 86 | `04_image_generation\` | `03_image_generation\` (wrong folder index) | | 51-56 | Short vague prompt | Comprehensive prompt required (see §3) | | 59-106 | Short vague prompts | Comprehensive prompts required (see §3) | | 87 | `$validPattern` regex uses flat naming | Landing page uses **directory-based** image nesting (`c1/slide-0.png`), not flat files (`carousel.1.0.png`) | ### Folder index map (correct) | Index | Purpose | Used by | |-------|---------|---------| | 01 | Content plan | content-plan-generator | | 02 | Prompts & copy (carousels + blogs) | carousel-prompt-generator, blog-post-generator | | 03 | Image generation | manual step | | 04 | Infographic briefs | infographic-brief-generator | | 05 | Landing page | monthly-drop-landing-page | | 06 | Scheduling | human | | 07 | Report | performance-report-generator | ## 3. Prompt Template (Replaces Short Prompts) Every `opencode run` prompt must follow this structure: ``` [AUTO-MODE] Use the [skill-name] for [Brand], cycle [Cycle]. Brand: [Brand] Language: [Language] Brand directory: Brands/[Brand] Content plan: Brands/[Brand]/03_monthly_cycles/[Cycle]/01_content_plan/output/[output-file].html Brand guide: Brands/[Brand]/[Brand]_brand_guide.md Direction: [1-3 lines of strategic direction] Deliverables: - Carousels: [N] - Blog posts: [N] - [other] Output: Brands/[Brand]/03_monthly_cycles/[Cycle]/[section]/output/ IMPORTANT: Generate .md then .html immediately. Do NOT ask for approval at any step. Proceed automatically. ``` ### Actual prompts used (working) #### Stage 1 — Content Plan ``` [AUTO-MODE] Use the content-plan-generator skill for PayWise, cycle 2026-09_SEP. Brand: PayWise Language: English Brand directory: Brands/PayWise Direction: Post-90-day roadmap maintenance. Keep activation focus. Continue Phase 1 execution: activation over acquisition. September 2026 bill cycle provides natural urgency for bill-payer content. Deliverables: - Carousels: 8 - Blog posts: 4 - Newsletters: 4 - Infographics: 2 Output: Brands/PayWise/03_monthly_cycles/2026-09_SEP/01_content_plan/output/ IMPORTANT: Generate .md then .html immediately. Do NOT ask for approval at any step. Proceed automatically. ``` #### Stage 2 — Carousel Prompts ``` [AUTO-MODE] Use the carousel-prompt-generator skill for PayWise, cycle 2026-09_SEP. Content plan: Brands/PayWise/03_monthly_cycles/2026-09_SEP/01_content_plan/output/PayWise_Content_Plan_SEPTEMBER_2026.html Brand guide: Brands/PayWise/PayWise_brand_guide.md Brand directory: Brands/PayWise Language: English Output: Brands/PayWise/03_monthly_cycles/2026-09_SEP/02_prompts_and_copy/output/ IMPORTANT: Generate .md then .html immediately. Do NOT ask for approval at any step. Proceed automatically. ``` #### Stage 3 — Blog Posts ``` [AUTO-MODE] Use the blog-post-generator skill for PayWise, cycle 2026-09_SEP. Content plan: Brands/PayWise/03_monthly_cycles/2026-09_SEP/01_content_plan/output/PayWise_Content_Plan_SEPTEMBER_2026.html Brand guide: Brands/PayWise/PayWise_brand_guide.md Knowledge base: Brands/PayWise/01_knowledge_base/ Brand directory: Brands/PayWise Language: English Output: Brands/PayWise/03_monthly_cycles/2026-09_SEP/02_prompts_and_copy/output/ IMPORTANT: Generate .md blog posts then generate .html immediately. Do NOT ask for approval at any step. Proceed automatically. ``` #### Stage 4 — Infographic Briefs ``` [AUTO-MODE] Use the infographic-brief-generator skill for PayWise, cycle 2026-09_SEP. Content plan: Brands/PayWise/03_monthly_cycles/2026-09_SEP/01_content_plan/output/PayWise_Content_Plan_SEPTEMBER_2026.html Brand guide: Brands/PayWise/PayWise_brand_guide.md Brand directory: Brands/PayWise Language: English Output: Brands/PayWise/03_monthly_cycles/2026-09_SEP/04_infographic_briefs/output/ IMPORTANT: Generate .md then .html immediately. Do NOT ask for approval at any step. Proceed automatically. ``` #### Stage 5 — Landing Page ``` [AUTO-MODE] Use the monthly-drop-landing-page skill for PayWise, cycle 2026-09_SEP. Content plan: Brands/PayWise/03_monthly_cycles/2026-09_SEP/01_content_plan/output/PayWise_Content_Plan_SEPTEMBER_2026.html Carousel prompts: Brands/PayWise/03_monthly_cycles/2026-09_SEP/02_prompts_and_copy/output/PayWise_Carousel_Prompts_SEPTEMBER_2026.html Blog posts: Brands/PayWise/03_monthly_cycles/2026-09_SEP/02_prompts_and_copy/output/PayWise_Blog_Posts_SEPTEMBER_2026.html Infographic briefs: Brands/PayWise/03_monthly_cycles/2026-09_SEP/04_infographic_briefs/output/PayWise_Infographic_Briefs_September_2026.html Brand guide: Brands/PayWise/PayWise_brand_guide.md Brand directory: Brands/PayWise Output: Brands/PayWise/03_monthly_cycles/2026-09_SEP/05_landing_page/output/ IMPORTANT: Generate the landing page immediately. Do NOT ask for approval at any step. Proceed automatically. ``` ## 4. Image Naming (Landing Page) The landing page uses **directory-based nesting** for images, not flat filenames: ``` src/assets/paywise/carousels/c1/slide-0.png (not carousel.1.0.png) src/assets/paywise/carousels/c1/slide-1.png src/assets/paywise/carousels/c2/slide-0.png src/assets/paywise/newsletters/newsletter.1.png src/assets/paywise/newsletters/email1-story.png src/assets/paywise/blogs/blog1-banner.png src/assets/paywise/blogs/blog1-story.png ``` The skill auto-generates 1×1 pixel placeholder PNGs for all image paths referenced in `paywise-content.ts`. It scans image extensions from a list: `[".png", ".jpg", ".webp", ".jpeg"]`. **Consequence:** The script's `$validPattern` regex uses flat naming (`carousel.\.\d+\.\d+|blog\.\d+...`) — this won't match the actual convention if image validation runs on the landing page output. ## 5. Vercel Deployment Flow ### What went wrong First `vercel --prod --yes` created a **new project** called `deigo123/output` instead of deploying under the existing `paywise-monthly-drops` project. The `.vercel/project.json` was created pointing to the wrong project ID. Vercel project listing from the account: | Project | Latest URL | |---------|-----------| | `output` | https://output-neon-three.vercel.app ❌ | | `paywise-monthly-drops` | https://paywise-monthly-drops.vercel.app ✅ | | `test-monthly-drop` | https://test-monthly-drop.vercel.app | ### Fix ```powershell Set-Location $LandingPageOutput vercel link --project paywise-monthly-drops --yes vercel --prod --yes ``` ### Notes - `vercel.json` included in the template uses `api/index.js` serverless routing for TanStack Start SSR — framework auto-detection works correctly - Build output goes to `dist/client/` (set in vercel.json) - `npx vite build` succeeds in ~5 seconds (cached on subsequent runs) - The `--confirm` flag is deprecated (now `--yes`) - The `--name` flag is deprecated ## 6. Inline Data vs External Files The skill-generated HTML files (content plan, blog posts, carousel prompts, infographic briefs) are **self-contained** — all styling, scripts, and content are inline in each `.html` file. No separate CSS or JS assets are linked. This means: - **Copying to `public/`** — the landing page skill copies content-plan.html and blog-posts.html into `05_landing_page/output/public/` so the TanStack app can link to them via `` - The carousel prompts HTML and infographic briefs HTML are NOT copied to public/ — only content plan + blog posts get copied - Each `.html` file includes dark/light toggle, search, filter controls, and copy-to-clipboard ## 7. Observations for the Script Creator ### opencode run invocation ``` opencode run "[AUTO-MODE] Use the skill..." ``` The `"$Prompt"` pattern with a PowerShell here-string works, but: - Variables like `$Brand` and `$CyclePath` **are** interpolated inside the here-string - The prompt must be a **single quoted string** or **double-quoted here-string** depending on whether you want variable expansion - Recommended: use double-quoted here-string `@"..."@` for variable interpolation ### Sub-skill loading Each skill auto-loads its sub-skills: - `content-plan-generator` → `content-strategy`, `copy-editing` - `carousel-prompt-generator` → `image`, `marketing-psychology` - `blog-post-generator` → `brainstorming`, `copywriting`, `seo-audit`, `ai-seo` - `infographic-brief-generator` → `image` - `monthly-drop-landing-page` → `image` No need to specify these in the prompt — they're declared in each SKILL.md. ### Stage-by-stage guidance needed - **Stages 1-4** require the brand guide path explicitly. The content-plan-generator does a dual-path lookup for brand guides, but downstream skills expect it as a prompt parameter - **Stage 5 (landing page)** requires ALL previous output file paths explicitly — it doesn't scan the cycle folder - The direction/deliverable breakdown is critical for Stage 1 — without it, the skill asks questions ### Timeouts | Stage | Expected time | Safe timeout | |-------|---------------|--------------| | Content plan | ~5 min | 15 min | | Carousel prompts | ~3 min | 10 min | | Blog posts | ~5 min | 15 min | | Infographic briefs | ~2 min | 10 min | | Landing page | ~8 min (incl npm install + build + deploy) | 20 min | ## 8. Generated Files (PayWise 2026-09_SEP) ``` 01_content_plan/output/ ├── PayWise_Content_Plan_SEP_2026.md (34 KB) └── PayWise_Content_Plan_SEPTEMBER_2026.html (96 KB) 02_prompts_and_copy/output/ ├── PayWise_Carousel_Prompts_SEPTEMBER_2026.md (60 KB) ├── PayWise_Carousel_Prompts_SEPTEMBER_2026.html (86 KB) ├── PayWise_Blog_Posts_SEPTEMBER_2026.md └── PayWise_Blog_Posts_SEPTEMBER_2026.html 04_infographic_briefs/output/ ├── PayWise_Infographic_Briefs_September_2026.md └── PayWise_Infographic_Briefs_September_2026.html 05_landing_page/output/ ├── public/ │ ├── content-plan.html (copied from 01) │ └── blog-posts.html (copied from 02) ├── src/ │ ├── lib/paywise-content.ts (inline content data) │ ├── routes/index.tsx (landing page component) │ └── routes/__root.tsx (shell layout + SEO meta) ├── dist/ (built output) ├── vercel.json ├── .vercel/project.json └── api/index.js ``` ## 9. Deliverable Count | Type | Count | |------|-------| | Carousels | 8 | | Blog posts | 4 | | Newsletters | 4 | | Social posts | 8 | | Infographics | 2 | | Push notifications | 4 | | **Total** | **30** |