Hot topics are only used for discovery; the final result is an auditable production decision: why do it now, who is it for, what makes the argument valid, which duplicate angles exist on Douyin, why the other candidates were eliminated, and how to review after publishing according to a fixed window.
Boundaries
- This skill is the sole lead writer of ①, writing signals, candidates, source-health, and
00-选题.*。 laohan-douyinsousuoonly writes00-抖音搜索证据.{json,md}; the same Agent host executes according to bianpai routing, and does not make programmatic skill-to-skill calls.- ② only writes the talking-head script; ① does not generate body text, outline paragraphs, or cover.
- ⑤ only performs complete fact-checking; ① must still find at least one PRIMARY original source for the final factual premise.
- Do not install new browsers, crawlers, Python runtime, or third-party skills. For Douyin platform access, use only the installed OpenCLI.
- The same event can form an opinion candidate and a tutorial candidate; when the audience task, title promise, and content path are truly different, they can enter comparison separately. ②—④ follow the selected lane and do not mix writing.
Input
Episode mode must read:
- This episode's
episode-config.jsonand00-编排/frozen artifacts. - Feedback snapshots explicitly registered for this episode; if none, record
NOT_AVAILABLE, and do not scan old episodes to guess experience. - This round's real signals and Douyin search evidence.
The standard Episode is fixed as REVIEW_GATED: AI independently completes discovery and candidates, but must not choose on Jeffrey's behalf. When Jeffrey explicitly gives a topic, go to USER_SEED, and still must provide at least one real alternative candidate, Douyin evidence collection, PRIMARY evidence, and a measurement contract; the final result also goes through emotional and expressive-desire screening.
When what Jeffrey gives is a software, method, or series direction, first go toUSER_DIRECTION_RESEARCH: read the projectdocs/系列选题研究与分期规格.md, and complete targeted searches on four platforms, content-level breakdown, demand judgment, series phasing, and single-episode material package. It does not run unrelated 9-account broad scans to pad hot topics. OnlyDEMAND_VALIDATEDcan enter a series of three episodes or more,EXPERIMENTAL_ONE_OFFenters only a single episode,DIRECTION_REJECTEDstops. A formal episode must still provide alternative candidates and go through Jeffrey's emotional screening.
Workflow
1. Collect current signals
Write first00-选题-signals.json.discovery_mode: no direction isAUTONOMOUS_SCAN; Jeffrey has already given direction asUSER_DIRECTION_RESEARCH. The latter writes thenode scripts/check-series-research.mjsthat has passedseries_research_pathand the SHA intodirection_research, and registers the four routes of Bilibili, Xiaohongshu, Douyin, and Zhihu separately as signal sources.DEMAND_VALIDATEDAt least two platforms have real demand signals;EXPERIMENTAL_ONE_OFFenter a single episode only based on verified official new events, Jeffrey's personal experience, or niche-task evidence in the research package, and do not force fabrication of popularity on two platforms.
Episode mode executes the sole deterministic entry point:
node ~/Documents/laohan-skills/laohan-redian/scripts/collect-topic-signals.mjs \
--episode episodes/<slug>
AUTONOMOUS_SCANThe candidate sources are fixed as three lines: recent scanning of 9 registered Douyin benchmark accounts account by account, comprehensive hot-topic scanning,script-pool/Jeffrey个人表达池.md. The default discovery and display priority isBENCHMARK_CREATOR(1) > BROAD_HOTSPOT(2) > PERSONAL_EXPRESSION(3); this is the topic-finding efficiency order, not an automatic selection score; personal topics can still win after obtaining public interest evidence. The default routes for comprehensive hot topics are AIHOT, Hacker News, Zhihu, Weibo, 36kr, Bilibili, Douyin Hot List, Toutiao, Tieba, and Hupu; if one route fails, record it truthfully, and the other hot topic routes continue, but if any of the 9 benchmark accounts fails, candidate generation stops, and a normal empty result is recordedEMPTYand counted as complete. Only pass this when the hot topic route needs to be narrowed --sources, and this cannot be used to skip the benchmark accounts and the personal pool.
The script only writes:
00-选题-signals.json- Initial
00-选题-source-health.json
The script does not select topics, does not access old episodes, and does not call douyin-ai.js。
2. Standardize, deduplicate, and form candidates
Read signals and cluster the same factual event by stable signal id; exclude duplicate expressions with the same URL/promise/path. Benchmark accounts are only used to distill motifs, public needs, and anomalous signals, not to copy titles, copy, cases, or conclusions. The same event generates two forms only when "help the audience make a judgment" and "take the audience through completing a task" each hold separately. Write schema 3 00-选题-candidates.json, first use the top-level screening_summary to leave the filtering chain, then write at least two genuinely different shortlist candidates.screening_summary contains only:
raw_signal_count: the actual total number of results in signals;event_cluster_count: the total number of event clusters after deduplication.longlist: when there are enough valid events, record 8–12 items; when there are fewer than 8, record all of them. Each item contains a uniqueevent_cluster_id、working_title, a non-emptysignal_ids, a positive integersource_count、disposition: SHORTLISTED|REJECTED, and a specificreason。- Each final candidate's
event_cluster_idmust be marked in the longlistSHORTLISTED. Do not add intermediate files, extra nodes, or a second scoring system.
For the same event, viewpoint/tutorial variants may be counted separately when the audience task, title promise, and content path differ. Each item must have:
Before forming candidates, restore the original analysis: mark relevance using direct terms such as "AI/GPT/Claude/large model/robot/automation/programming/side hustle" and indirect terms such as "education/career/consumption/entrepreneurship/workplace", but retain marginal signals that may generate new angles; count content types such as installation tutorials/advanced tips/methodology/comparative reviews/hands-on/resource recommendations; mark multi-platform resonance, single-platform exclusivity, crowded angles, and opportunities not covered by competitors. They are used to expand candidates, not to replace the later PRIMARY and Douyin keyword verification.
- Unique
id, stable non-emptyevent_cluster_id, non-emptywhy_now、title、content_form: opinion-video|tutorial-video、audience_level: BEGINNER|INTERMEDIATE|ADVANCED、audience_problem、audience_promise、thesis。 candidate_originmust registerprimary_lane, the correspondingpriority_rank, non-emptyorigin_signal_idsandcorroborating_lanes. Cross-verification can improve credibility, but it cannot disguise a personal expression source as a benchmark viral source.tensionmust registertype: CONFLICT|MISCONCEPTION|COUNTERINTUITIVE|TRADEOFF、common_assumption、jeffrey_positionand aconflict_statementthat can be fulfilled by the main text in one sentence. Writing only a domain name, product launch, or "worth paying attention to" does not count as a candidate.creator_fitmust clearly statebasis: FIRSTHAND_EXPERIENCE|BUILT_OR_TESTED|OWNED_EVIDENCE|LONG_TERM_PRACTICE|RESEARCHED_JUDGMENT|NOT_ESTABLISHED、why_jeffreyanddistinctive_judgment. It answers "why Jeffrey should talk about it, what his basis is, and what judgment it adds compared with a generic retelling." SELECTED does not allowNOT_ESTABLISHED; when there is no firsthand experience,RESEARCHED_JUDGMENTmay be used, but it must form an independent judgment with evidentiary boundaries, and "I also paid attention to it" cannot be passed off as a personal advantage.assumed_prerequisitesandjargon_to_explainare string arrays. BEGINNER candidates must include the key tools, commands, and migration/import concepts in the title and argument in the explanation checklist, and cannot merely increase theaudience_fitscore.- Non-empty
signal_idsandevidence_ids。 - Non-empty
platform_query_intent;platform_alignmentcontainsstatus: ALIGNED|ADJACENT|CONTRADICTED|UNRESOLVED|UNAVAILABLE, non-emptyrationaleandevidence_ids. When there are platform results, evidence ids must be real; when platform access fails, writeUNAVAILABLEand an empty array. content_gapcontainsstatus: CONFIRMED|NOT_CONFIRMED|UNAVAILABLE, non-emptyrationaleandevidence_ids. Only when the platform directly provides search volume, supply or gap evidence can the first two be written; search result counts, missing interaction fields, or model judgments must never be passed off as content gaps.UNAVAILABLEis legal and does not participate in mechanical elimination.- non-empty
claim_evidence_map; each entry contains a uniqueclaim_id, non-emptyclaim、evidence_ids. It must bind technical facts to PRIMARY; when platform evidence is available, bind "what people on the platform care about" to PLATFORM_SIGNAL, and must not let an adjacent keyword endorse another argument. When the platformUNAVAILABLE, do not fabricate a PLATFORM_SIGNAL claim. scorecardseven-dimension integer 1—5:audience_fit、evidence_strength、platform_relevance、differentiation、creator_fit、production_feasibility、learning_value。- non-empty
rationale. Before Jeffrey's screening, all usedisposition: AWAITING_JEFFREY; AI only displays candidates, evidence and risks, and must not directly mark SELECTED.
Scores are challengeable candidate comparisons, not traffic forecasts. Heat cannot replace audience value, evidence strength, differentiation or filmability. SELECTED can be ALIGNED, ADJACENTwith a clear differentiation explanation, or, when discovery and PRIMARY are sufficient, UNAVAILABLEthat honestly explains the scope of the gap; platform absence lowers platform_relevance confidence, but cannot eliminate a candidate on its own.CONTRADICTED|UNRESOLVED must not be selected. Before a tutorial candidate is written as definitive steps, it must still be registered in tutorial_proof , within this period status: VERIFIED, non-empty evidence_path、evidence_sha256and version_boundary . recovery。
3. Perform Douyin keyword verification on the shortlist
Design a specific query for each of 1—3 shortlisted candidates, and have the same host execute laohan-douyinsousuo episode mode. Must obtain 00-抖音搜索证据.json and .md before continuing.
OK: cite real result ids, and clearly state the audience intent that the query actually proves. When it directly supports the candidate title promise, audience task andwhy_now, markALIGNED; when it only supports the same product, migration heat or an adjacent concept, markADJACENT. Prefer adding more direct queries, but do not automatically eliminate a differentiated new angle just because it lacks content with the exact same title.EMPTY_OR_FIELD_UNAVAILABLE: write only "platform evidence pending", and must not write "no one is doing it/blue ocean".- OpenCLI login or adapter all failed: keep the real FAILED evidence, mark
platform_alignmentandcontent_gapasUNAVAILABLE; as long as discovery and PRIMARY are sufficient, continue comparing, and do not treat platform absence as a blocker.
4. Return to the PRIMARY original source
For the final candidates' factual premises, look up official websites, official announcements, papers, product documentation or original public records. Platform hot lists, search results, and media paraphrases can only be PLATFORM_SIGNAL or SECONDARY。
Write PRIMARY and PLATFORM_SIGNAL evidence into the candidate file; each entry has a stable id、source、source_type、url、retrieved_at. When PRIMARY is missing, narrow the argument to the provable scope; if it still cannot hold, switch candidates or BLOCKED.
5. Jeffrey emotion and expression desire screening
After the candidates are complete, enterWAITING_FOR_JEFFREY_EMOTION_SELECTION. Display 3—5 candidates at a time, and ask Jeffrey to choose one based on a genuine first reaction, or explicitly choose "all feel indifferent".
- Select one: record
first_reaction、challenge_or_addition、firsthand_detail、would_say_without_heat=true. First change the sole candidate toSELECTED, and the rest toREJECTED, then write schema 100-选题-Jeffrey筛选.jsonBind the current candidate SHA and the unique candidate ID. - All no-preference: write
status=REJECTED_ALL, bind the current candidate SHA, and recordrejection_reason、strongest_near_missandrescan_direction. EnterTOPIC_RESCAN_REQUIRED, and in the same 01 task return to the three-way scan; do not force SELECTED, generate a final topic, or enter ②. Before a new round of candidates replaces the old candidates, these four items must be written as-is along with the old candidate SHA into the new00-选题-candidates.json.screening_summary.rejection_history[]; validator uses this to switch fromTOPIC_RESCAN_REQUIREDback toWAITING_FOR_JEFFREY_EMOTION_SELECTION. The final acceptance record may overwrite the screening file, but the rejection history remains in the candidate file.
Without a SHA-closed Jeffrey record, no final topic may be generated.
6. Write the final decision and source health
Update 00-选题-source-health.json, recording for each channel:
- Unique
source_idandsource_role: DISCOVERY|BENCHMARK_CREATOR|PERSONAL_EXPRESSION|DOUYIN_SEARCH|PRIMARY_PROOF. schema 3 must retain the latter two local discovery roles; the personal expression pool allowsEMPTY, while benchmark accounts only allow the fully scannedOK|EMPTY。 - Actual
command_or_url、attempted_at、status、result_count。 - For this period relative to
result_fileand actualresult_sha256。 - FAILED writes
error; SKIPPED writesreason。
The status must be consistent: the number of OK entries is greater than 0, and the number of EMPTY/FAILED/SKIPPED entries is 0. At least one DISCOVERY is OK, one DOUYIN_SEARCH has a real attempt record, and one PRIMARY_PROOF is OK; DOUYIN_SEARCH may be FAILED, but must be bound to this period's Douyin evidence file and the original error.
Write schema 3 00-选题.json, retain the original schema 2 fields, and bind the candidate selected by Jeffrey. Finally execute:
node ~/Documents/laohan-skills/laohan-redian/scripts/check-topic-contract.mjs --episode episodes/<slug>
Only outputPASS redian topic contract schema=3counts as ① complete.
schema_version: 2、selected_candidate_id, non-emptyrejected_candidate_ids。- Copy as-is the selected item's
content_form、audience_level、audience_promise、creator_fit、assumed_prerequisites、jargon_to_explain、platform_query_intent、platform_alignment、content_gapandclaim_evidence_map。 audience、thesis、evidence、selection_rationale、not_do_reason。- All evidence belongs to the selected candidate, and at least one is PRIMARY; when the platform is available, at least one PLATFORM_SIGNAL,
platform_alignment.status=UNAVAILABLEmay be absent when . - experiment contains a unique primary intervention, legal
metric_keys, positive integerT+N、observation_window_unit: DAYand per-keymetric_targets。
Each metric target:
{
"key": "avg_duration_sec",
"direction": "INCREASE",
"baseline_ref": "recent_5_median",
"measurement_source": "douyin_creator_center"
}
Finally write 00-选题.md, explaining only the real decisions in the machine contract, without adding unregistered facts.
Failure handling
| Trigger condition | Handling |
|---|---|
| A single discovery source fails | Record FAILED; other sources that satisfy the role contract may continue |
| All discovery sources have no results | BLOCKED, do not choose a topic from model memory |
| Douyin returns a legal empty array | Record EMPTY; do not infer that there is no competition |
| OpenCLI login/adapter all-path failure | Record platform evidence as UNAVAILABLE and continue; do not install an alternative scraper, do not infer a blue ocean |
| The final candidate has no PRIMARY | Narrow the thesis or switch candidates; if still none, BLOCKED |
| Jeffrey has no preference for any candidate | WriteREJECTED_ALLand enterTOPIC_RESCAN_REQUIRED; rescan according to the rejection reasons, do not enter ② |
| Platform results support only adjacent topics | Mark ADJACENT, supplement the query; if still adjacent, truthfully explain the differentiation and risks, may participate in the final comparison, must not pretend to be directly aligned |
| The tutorial candidate has no real local execution evidence | Keep REJECTED; may be retained as a pending-verification candidate, must not be written as a tutorial that is already deliverable |
| Candidate cannot be measured under the existing ⑬ metric | Switch intervention/metric or switch candidate |
Anti-patterns
❌ “All three platforms are hot, so let’s do this one.”
✅ “Candidate C02 simultaneously addresses the target audience problem, PRIMARY supports the factual premise, and Douyin evidence shows existing content is concentrated on feature introductions, while this issue differentiates through the cost of real workflows; C01/C03 were eliminated due to weak evidence or being unfilmable.”
❌ “Some people on Douyin searched for Claude Code migration, so that proves the ‘validation loop’ is a current platform demand.”
✅ “That result only proves migration/import demand; mark it ADJACENT; continue searching for direct intent such as validation failures, launch regressions, etc. If there are still no direct results, you may include the ‘validation loop’ as a differentiated viewpoint in the comparison, but make it clear that platform evidence only supports an adjacent demand.”
❌ “0 search results, so this is a blue ocean.”
✅ “The search executed successfully but returned 0 results; record this as platform evidence undetermined, and do not use it to judge competition.”
Non-Episode mode
When the user only wants a hot-topic brief, you may run the same collection script into a temporary directory and then return a summary of the current signals; do not write to the episode source of truth. When the user only wants to search Douyin, route directly laohan-douyinsousuo。