Skip to content

Bookends — Strong Openings & Closings

The Bookends module (fabric_workflow_sdk.bookends) provides prompt-building utilities that generate rich, structured guidance for powerful content openings and closings. It works across all artifact types — videos, images, captions, blog posts, series, and ad sequences.

from fabric_workflow_sdk import build_bookends_prompt
# Get both opening and ending guidance in one call
prompt_block = build_bookends_prompt(
artifact_type="video",
platform="tiktok",
mood="edgy",
hook_type="question",
)
# Inject into your LLM prompt
full_prompt = f"""Write a script about productivity hacks.
{prompt_block}
"""

The module supports these artifact types, each with tailored guidance:

Artifact TypeOpening FocusClosing Focus
videoFirst 3 seconds — life or death for retentionDirect-to-camera CTA with hook coherence
image2-4 word overlay text, emotional not descriptiveCaption CTA matching visual register
blogHook as opening line, not topic sentenceClosing paragraph earns the CTA
captionFirst line above the fold stops the scrollSingle clear action, tone-matched
seriesPart 1: strongest hook. Part 2+: callbackSpecific cliffhanger (not “stay tuned”)
adPhase-aware: pain recognition firstEscalating: no CTA → soft → hard

12 closing strategies that work across all artifact types:

TypeStrategyExample
followSubscription ask”Follow — I drop one of these every day.”
saveBookmark urgency”Save this before the algorithm buries it.”
commentEngagement prompt”Drop your hottest take below.”
shareSocial spread”Tag someone who needs to hear this.”
challengeAction dare”Try this for 7 days. Come back and tell me.”
cliffhangerSerial hook”But here’s the part nobody talks about… tomorrow.”
questionIdentity mirror”So which one are you?”
identityTribal belonging”If you made it this far, you’re different.”
proof_requestSkeptic redirect”Don’t believe me? Try it yourself.”
value_promiseContent contract”I break down one of these every week.”
mic_dropNo ask, devastating final lineStands alone — no CTA needed.
callbackLoop to openingReferences the hook, closes the circle.

8 arc patterns that describe how to transition into the close:

StyleArc
mic_dropBuild tension, release with one devastating line
callback_loopReference the opening, circular “oh wow” moment
cliffhanger_bridgeResolve this piece, plant seed for next
emotional_peakEscalate emotion, CTA rides the wave at peak
pattern_breakShift tone/pace abruptly to snap attention
social_proof_closeEnd with evidence, CTA while credibility is highest
story_resolveComplete narrative arc, CTA as natural next chapter
rapid_recapQuick-fire summary, CTA as “now act” punchline

8 opening frameworks:

StyleApproach
bold_claimStrong, specific, slightly uncomfortable statement
questionAsk something the audience cannot ignore
contrarianChallenge conventional wisdom head-on
story_dropStart mid-story, no preamble
pain_pointName their exact frustration
shock_statLead with a surprising number or fact
identity_call”If you’re a [type]…” — instant self-selection
pattern_interruptBreak the expected format

The main entry point. Returns both opening and ending prompt blocks combined.

from fabric_workflow_sdk import build_bookends_prompt
block = build_bookends_prompt(
artifact_type="video", # video | image | blog | caption | series | ad
platform="tiktok", # tiktok | youtube shorts | instagram | linkedin | twitter | threads
mood="edgy", # mood/tone descriptor
hook_type="question", # optional — drives CTA strategy recommendation
emotional_trigger="curiosity", # optional — refines CTA selection
cta_style=None, # optional — formula override (free text)
ending_style=None, # optional — force a specific ending arc
opening_style=None, # optional — force a specific opening framework
)

Returns only the opening prompt block.

from fabric_workflow_sdk import build_opening_prompt
opening = build_opening_prompt(
artifact_type="caption",
platform="instagram",
mood="conversational",
hook_type="pain_point",
emotional_trigger="empathy",
opening_style="story_drop", # optional override
)

Returns only the ending prompt block.

from fabric_workflow_sdk import build_ending_prompt
ending = build_ending_prompt(
artifact_type="video",
platform="tiktok",
mood="edgy",
hook_type="contrarian",
emotional_trigger="outrage",
cta_style=None, # optional formula override
ending_style="mic_drop", # optional override
)

Pure mapping logic — recommends the best CTA strategy based on hook type and emotional context.

from fabric_workflow_sdk import recommend_cta_strategy
strategy = recommend_cta_strategy(
hook_type="question",
emotional_trigger="curiosity",
artifact_type="video",
platform="tiktok",
)
# Returns:
# {
# "cta_type": "callback",
# "ending_style": "callback_loop",
# "reasoning": "A question hook creates a natural bridge to a callback CTA...",
# "examples": ["Remember that question I asked at the start? Now you know the answer.", ...]
# }

The recommendation engine maps hook types to optimal CTA strategies:

Hook TypeRecommended CTARecommended Ending Style
questioncallbackcallback_loop
contrarianmic_dropmic_drop
cliffhangercliffhangercliffhanger_bridge
pain_pointchallengeemotional_peak
shockproof_requestpattern_break
social_proofsharesocial_proof_close
storycallbackstory_resolve
fomosaverapid_recap

Platform adjustments are applied automatically (e.g., Instagram favors save over follow).

The ai_shorts pipeline uses bookends automatically. Pass optional overrides via input:

input = {
"topic": "Why cold showers boost productivity",
"hook_type": "contrarian", # drives CTA strategy
"emotional_trigger": "surprise", # refines recommendation
"cta_style": "mic_drop", # force a specific CTA type
}

When using formula_shorts, the formula’s cta_style field flows through to build_ending_prompt() automatically:

# In your formula JSON:
{
"script": {
"hook_type": "question",
"cta_style": "always end with a challenge — dare the viewer to try it"
}
}

Use build_bookends_prompt() in your content generation prompts:

from fabric_workflow_sdk import build_bookends_prompt
bookends = build_bookends_prompt(
artifact_type="blog",
platform="linkedin",
mood="professional",
hook_type="bold_claim",
)
prompt = f"""Write a LinkedIn article about remote work productivity.
{bookends}
Write 800-1200 words. Include specific examples and data.
"""

For multi-part series, the bookends module provides cliffhanger/callback guidance:

from fabric_workflow_sdk import build_ending_prompt, build_opening_prompt
# Part 1: Strong hook, cliffhanger ending
part1_ending = build_ending_prompt(
artifact_type="series",
platform="twitter",
mood="dramatic",
ending_style="cliffhanger_bridge",
)
# Part 2+: Callback opening, builds on previous
part2_opening = build_opening_prompt(
artifact_type="series",
platform="twitter",
mood="dramatic",
opening_style="story_drop",
)

The module is phase-aware for advertising content:

from fabric_workflow_sdk import build_ending_prompt
# Phase 1: Awareness — no CTA
phase1 = build_ending_prompt("ad", "instagram", "empathetic")
# Phase 3: Conversion — hard CTA with friction removal
phase3 = build_ending_prompt("ad", "instagram", "urgent", cta_style="direct conversion")

The module includes platform-specific CTA guidance that reflects how each platform’s algorithm rewards different engagement signals:

TikTok

Comments + shares drive distribution. Duet/stitch CTAs work. The algorithm treats comments as intent signals.

YouTube Shorts

Subscribe + like signals matter most. “Watch the full video” bridges to long-form. End screens don’t work on Shorts.

Instagram

Saves are the strongest signal. Story shares amplify reach. Profile visits from Reels drive follower growth.

LinkedIn

Thoughtful comments signal quality. The audience punishes engagement-bait. Invite professional perspective, not agreement.

All taxonomies are exported as lists for use in extraction, classification, or UI:

from fabric_workflow_sdk import CTA_TYPES, ENDING_STYLES, OPENING_STYLES
print(CTA_TYPES)
# ['follow', 'save', 'comment', 'share', 'challenge', 'cliffhanger',
# 'question', 'identity', 'proof_request', 'value_promise', 'mic_drop', 'callback']
print(ENDING_STYLES)
# ['mic_drop', 'callback_loop', 'cliffhanger_bridge', 'emotional_peak',
# 'pattern_break', 'social_proof_close', 'story_resolve', 'rapid_recap']
print(OPENING_STYLES)
# ['bold_claim', 'question', 'contrarian', 'story_drop', 'pain_point',
# 'shock_stat', 'identity_call', 'pattern_interrupt']

Defaults are available via constants:

from fabric_workflow_sdk import DEFAULT_CTA_TYPE, DEFAULT_ENDING_STYLE, DEFAULT_OPENING_STYLE
# DEFAULT_CTA_TYPE = "follow"
# DEFAULT_ENDING_STYLE = "emotional_peak"
# DEFAULT_OPENING_STYLE = "bold_claim"