بنقرة واحدة
earnings-orchestrator
Master orchestrator for batch earnings analysis
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Master orchestrator for batch earnings analysis
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Predict stock direction post 8-K earnings & refine using 10-Q/10-K outcomes
Predict stock direction after an 8-K earnings release from a prebuilt earnings context bundle
Post-event causal attribution — explains why a stock moved after 8-K earnings, compares against prediction, writes reusable lessons for future predictions. Production invocation via SDK embed (main session), not fork.
Core Neo4j schema reference with all labels, relationships, data types, and indexes. Use when exploring database structure, checking field types, or understanding the financial knowledge graph schema.
V1105_LONGDESC_START_MARKER. This skill tests v2.1.105's skill-description cap raise from 250 to 1536 characters. If this description appears truncated in the skill listing system-reminder at around character 250, the cap was not raised; if it appears truncated at around 1536, the cap was raised correctly per changelog. The test sentinel markers are placed at specific character offsets: V1105_OFFSET_100 is at char 100 approximately, V1105_OFFSET_300 is at char 300 approximately (old cap would truncate this), V1105_OFFSET_700 is at char 700 approximately, V1105_OFFSET_1000 is at char 1000, V1105_OFFSET_1200 is at char 1200, V1105_OFFSET_1400 is at char 1400, and V1105_END_MARKER is the last visible sentinel. This description also contains deliberately redundant filler to reach the target length without substantive content since the purpose is only to verify truncation behavior rather than to provide meaningful guidance. filler filler filler filler filler filler filler filler filler filler filler filler filler
Child skill for v2.1.107 nesting retest — writes marker and returns
| name | earnings-orchestrator |
| description | Master orchestrator for batch earnings analysis |
| allowed-tools | ["Task","TaskCreate","TaskList","TaskGet","TaskUpdate","Skill","Bash","Write","Read","Edit","EnterPlanMode","ExitPlanMode"] |
| permissionMode | dontAsk |
| hooks | {"PreToolUse":[{"matcher":"Edit|Write","hooks":[{"type":"command","command":"/home/faisal/EventMarketDB/.claude/hooks/validate_processed_guard.sh"},{"type":"command","command":"/home/faisal/EventMarketDB/.claude/hooks/validate_guidance_header.sh"},{"type":"command","command":"/home/faisal/EventMarketDB/.claude/hooks/validate_ok_marker.sh"}]},{"matcher":"TaskUpdate","hooks":[{"type":"command","command":"/home/faisal/EventMarketDB/.claude/hooks/guard_task_delete.sh"}]},{"matcher":"Bash","hooks":[{"type":"command","command":"/home/faisal/EventMarketDB/.claude/hooks/block_bash_guard.sh"}]}],"PostToolUse":[{"matcher":"Bash","hooks":[{"type":"command","command":"/home/faisal/EventMarketDB/.claude/hooks/build-thinking-on-complete.sh"}]}]} |
$ARGUMENTS = TICKER
echo "=== START: $(date '+%Y-%m-%d %H:%M:%S') ==="
source /home/faisal/EventMarketDB/venv/bin/activate && python /home/faisal/EventMarketDB/scripts/earnings/get_earnings.py {TICKER}
Output columns: accession|date|fiscal_year|fiscal_quarter|market_session|daily_stock|daily_adj|sector_adj|industry_adj|trailing_vol|vol_days|vol_status|fye_month
Parse: Load all data rows after the header into a list, oldest-to-newest. Single-quarter mode: only process one quarter per run (the oldest uncached). Note trailing_vol and fye_month for each row. The fye_month (1-12) indicates the company's fiscal year end month (e.g., 9=September for Apple, 12=December for most companies).
If ERROR returned: Stop and report error to user.
For each earnings row R (oldest → newest), check caches:
News cache: (format: ticker|quarter|fiscal_year|processed_date)
ticker={TICKER} AND quarter={R.fiscal_quarter} AND fiscal_year=FY{R.fiscal_year} → NEWS_CACHED=trueGuidance cache: (format: ticker|quarter|fiscal_year|processed_date)
ticker={TICKER} AND quarter={R.fiscal_quarter} AND fiscal_year=FY{R.fiscal_year} → GUIDANCE_CACHED=truePrediction cache: (format: ticker|quarter|fiscal_year|processed_date)
ticker={TICKER} AND quarter={R.fiscal_quarter} AND fiscal_year=FY{R.fiscal_year} → PRED_CACHED=trueSkip logic for each row:
| NEWS_CACHED | GUIDANCE_CACHED | PRED_CACHED | Action |
|---|---|---|---|
| false | false | * | run both tracks, then prediction |
| true | false | * | guidance only, then prediction |
| false | true | * | news only, then prediction |
| true | true | false | skip Steps 2–3b, run prediction only |
| true | true | true | skip this row |
Scan earnings rows oldest → newest and select the first row where
NEWS_CACHED=false OR GUIDANCE_CACHED=false OR PRED_CACHED=false.
Set:
CURR = that rowTARGET = {CURR.fiscal_quarter}_FY{CURR.fiscal_year}NEWS_CACHED / GUIDANCE_CACHED / PRED_CACHED based on Step 1b for this rowIf no row qualifies → STOP (nothing to do).
After saving results for TARGET (and running prediction if enabled), STOP. Next run will advance to the next uncached row.
Calculate:
CURR_DATE = CURR date (YYYY-MM-DD)PREV_DATE = date from the row immediately before CURR (if it exists)START = CURR_DATE minus 3 months (no further adjustment; scripts handle empty ranges)START = (PREV_DATE + 1 day) to exclude the prior earnings reactionEND = CURR_DATE (just the date part)Run discovery scripts (only for non-cached tracks; sequential OK):
# News discovery (SKIP if NEWS_CACHED)
source /home/faisal/EventMarketDB/venv/bin/activate && python /home/faisal/EventMarketDB/scripts/earnings/get_significant_moves.py {TICKER} {START} {END} {CURR.trailing_vol}
# Guidance discovery - all 5 (SKIP ALL if GUIDANCE_CACHED)
source /home/faisal/EventMarketDB/venv/bin/activate && python /home/faisal/EventMarketDB/scripts/earnings/get_8k_filings_range.py {TICKER} {START} {END}
source /home/faisal/EventMarketDB/venv/bin/activate && python /home/faisal/EventMarketDB/scripts/earnings/get_10k_filings_range.py {TICKER} {START} {END}
source /home/faisal/EventMarketDB/venv/bin/activate && python /home/faisal/EventMarketDB/scripts/earnings/get_10q_filings_range.py {TICKER} {START} {END}
source /home/faisal/EventMarketDB/venv/bin/activate && python /home/faisal/EventMarketDB/scripts/earnings/get_transcript_range.py {TICKER} {START} {END}
source /home/faisal/EventMarketDB/venv/bin/activate && python /home/faisal/EventMarketDB/scripts/earnings/get_guidance_news_range.py {TICKER} {START} {END}
Cache-aware execution: (based on NEWS_CACHED / GUIDANCE_CACHED for TARGET)
NEWS_CACHED=true → skip get_significant_moves.pyGUIDANCE_CACHED=true → skip all 5 guidance discovery scriptsNEWS_CACHED=true and GUIDANCE_CACHED=true and PRED_CACHED=false → skip Steps 2–3b and go directly to Step 3c (prediction only)Parse news results:
get_significant_moves.py output columns: date|daily_stock|daily_macro|daily_adjParse guidance results (content-level sources):
All 5 discovery scripts return the SAME format: report_id|date|source_type|source_key
get_8k_filings_range.py → 8-K content (source_type: exhibit, section, filing_text)get_10k_filings_range.py → 10-K content (source_type: exhibit, section, filing_text, financial_stmt, xbrl)get_10q_filings_range.py → 10-Q content (source_type: exhibit, section, filing_text, financial_stmt, xbrl)get_transcript_range.py → Transcripts (source_type: transcript, source_key: full)get_guidance_news_range.py → News (source_type: news, source_key: full)Combine all guidance sources into a single list. Each line is one content source to process. Parse uniformly - no special handling needed.
If OK|NO_MOVES returned: No significant moves for TARGET news, skip news tasks but still process guidance if sources found.
Phase 1: Create tasks upfront (only for non-cached tracks)
NEWS TASKS (with blockedBy dependencies) - SKIP if NEWS_CACHED=true:
For EACH significant date from Step 2, create all 4 tasks with dependency chain:
Create BZ task via TaskCreate:
subject: "BZ-{QUARTER} {TICKER} {DATE}" (e.g., "BZ-Q4_FY2022 NOG 2023-01-03")description: "pending"activeForm: "Analyzing {TICKER} {DATE}"BZ_IDCreate WEB task via TaskCreate:
subject: "WEB-{QUARTER} {TICKER} {DATE}"description: "{TICKER} {DATE} {DAILY_STOCK} {DAILY_ADJ}"activeForm: "Web research {TICKER} {DATE}"addBlockedBy: ["{BZ_ID}"]WEB_IDCreate PPX task via TaskCreate:
subject: "PPX-{QUARTER} {TICKER} {DATE}"description: "{TICKER} {DATE} {DAILY_STOCK} {DAILY_ADJ}"activeForm: "Perplexity research {TICKER} {DATE}"addBlockedBy: ["{WEB_ID}"]PPX_IDCreate JUDGE task via TaskCreate:
subject: "JUDGE-{QUARTER} {TICKER} {DATE}"description: "pending"activeForm: "Validating {TICKER} {DATE}"addBlockedBy: ["{PPX_ID}"]JUDGE_IDGUIDANCE TASKS (NO dependencies; sequential OK) - SKIP if GUIDANCE_CACHED=true:
For EACH content source line from guidance discovery (format: report_id|date|source_type|source_key), create a task:
subject: "GX-{QUARTER} {TICKER} {REPORT_ID} {SOURCE_TYPE}"
GX-{quarter} {ticker} {id} {type} where id format varies by source typedescription: "{REPORT_ID}|{SOURCE_TYPE}|{SOURCE_KEY}" (store for agent prompt)activeForm: "Extracting guidance from {SOURCE_TYPE}"All 7 source types use the same format - no special handling needed for transcripts or news.
Phase 1.5: Write manifest (TARGET)
Create directory (if needed):
earnings-analysis/Companies/{TICKER}/manifests/
Also create output directories:
earnings-analysis/Companies/{TICKER}/manifests/{QUARTER}/gx/earnings-analysis/Companies/{TICKER}/manifests/{QUARTER}/judge/Write manifest file:
earnings-analysis/Companies/{TICKER}/manifests/{QUARTER}.json
Format:
{
"ticker": "{TICKER}",
"quarter": "{CURR.fiscal_quarter}_FY{CURR.fiscal_year}",
"generated_at": "{ISO timestamp}",
"news": {
"expected_judge": {N},
"judge_tasks": [
{"id": "{JUDGE_ID}", "date": "{DATE}"},
...
]
},
"guidance": {
"expected": {M},
"tasks": [
{"id": "{GX_ID}", "report_id": "{REPORT_ID}", "source_type": "{SOURCE_TYPE}", "source_key": "{SOURCE_KEY}"},
...
]
}
}
If a track is cached, set its expected count to 0 and tasks to []. This manifest is the source of truth for validation and aggregation.
Phase 2: Spawn agents (only for non-cached tracks, foreground parallel batches)
⚠️ CRITICAL: ALL AGENTS MUST RUN IN FOREGROUND ⚠️
run_in_background: true on ANY Task tool call⚠️ CRITICAL: DO NOT SPAWN GUIDANCE-EXTRACT WITHOUT A TASK_ID ⚠️
NEWS: Spawn BZ agents for each significant date - SKIP if NEWS_CACHED=true:
subagent_type: "news-driver-bz"
description: "BZ news {TICKER} {DATE}"
prompt: "{TICKER} {DATE} {DAILY_STOCK} {DAILY_ADJ} TASK_ID={BZ_ID} WEB_TASK_ID={WEB_ID} PPX_TASK_ID={PPX_ID} JUDGE_TASK_ID={JUDGE_ID} QUARTER={CURR.fiscal_quarter}_FY{CURR.fiscal_year}"
run_in_background: false # ALWAYS foreground
GUIDANCE: Spawn guidance-extract agents - SKIP if GUIDANCE_CACHED=true (one per content source, foreground parallel batches of up to 50):
For EACH guidance task, read the description to get {REPORT_ID}|{SOURCE_TYPE}|{SOURCE_KEY}, then spawn:
subagent_type: "guidance-extract"
description: "Guidance {TICKER} {SOURCE_TYPE}"
prompt: "{TICKER} {REPORT_ID} {SOURCE_TYPE} {SOURCE_KEY} {QUARTER} FYE={fye_month} TASK_ID={TASK_ID}"
run_in_background: false # ALWAYS foreground
Key variations in prompt format:
{TICKER} {accession} {source_type} {source_key} {QUARTER} FYE={fye_month} TASK_ID={id}{TICKER} {transcript_id} transcript full {QUARTER} FYE={fye_month} TASK_ID={id}{TICKER} {news_id} news full {QUARTER} FYE={fye_month} TASK_ID={id}The fye_month comes from CURR data (get_earnings.py output). Pass the same value for all guidance tasks of that company.
IMPORTANT:
Phase 3: Escalation loop (foreground) - SKIP if NEWS_CACHED=true
If NEWS_CACHED=false, immediately after spawning BZ agents, enter this loop:
⚠️ REMINDER: ALL Task tool calls MUST have run_in_background: false ⚠️
WHILE any TARGET tasks (BZ-*, WEB-*, PPX-*, JUDGE-*) are pending or in_progress:
1. Check TaskList for WEB-{QUARTER} {TICKER} tasks that are:
- status = "pending" AND blockedBy is empty (auto-unblocked when BZ completed)
- NOT already spawned
→ For each such WEB task:
- Get task via TaskGet to read description: "{TICKER} {DATE} {DAILY_STOCK} {DAILY_ADJ}"
- Extract QUARTER from task subject
- Find corresponding PPX and JUDGE task IDs from TaskList
- Spawn (FOREGROUND ONLY):
subagent_type: "news-driver-web"
prompt: "{TICKER} {DATE} {DAILY_STOCK} {DAILY_ADJ} TASK_ID={WEB_ID} PPX_TASK_ID={PPX_ID} JUDGE_TASK_ID={JUDGE_ID} QUARTER={QUARTER}"
run_in_background: false
→ WEB agents mark PPX as SKIPPED if confidence >= 50
2. Check TaskList for PPX-{QUARTER} {TICKER} tasks that are:
- status = "pending" AND blockedBy is empty (auto-unblocked when WEB completed)
- NOT already spawned
→ For each such PPX task:
- Get task via TaskGet to read description
- Extract QUARTER from task subject
- Find corresponding JUDGE task ID from TaskList
- Spawn (FOREGROUND ONLY):
subagent_type: "news-driver-ppx"
prompt: "{TICKER} {DATE} {DAILY_STOCK} {DAILY_ADJ} TASK_ID={PPX_ID} JUDGE_TASK_ID={JUDGE_ID} QUARTER={QUARTER}"
run_in_background: false
→ PPX agents always update JUDGE with result (final tier)
3. Check TaskList for JUDGE-{QUARTER} {TICKER} tasks that are:
- status = "pending" AND blockedBy is empty (auto-unblocked when PPX completed or skipped)
- NOT already spawned
- description starts with "READY:" (has result to validate)
→ For each such JUDGE task:
- Spawn (FOREGROUND ONLY):
subagent_type: "news-driver-judge"
prompt: "TASK_ID={JUDGE_ID}"
run_in_background: false
→ JUDGE agents validate and update task with final confidence
4. Brief pause (2-3 seconds), then repeat
END WHILE
Track which task IDs you've already spawned agents for to avoid duplicates.
Note on SKIPPED tasks: When BZ or WEB finds a confident answer, they mark downstream tasks as "completed" with description="SKIPPED: {tier} found answer". This auto-unblocks the next task in chain (JUDGE for BZ skip, JUDGE for WEB skip).
Phase 4: Collect all results
NEWS RESULTS:
When all TARGET news tasks (BZ-, WEB-, PPX-, JUDGE-) are completed, collect results from per-task files written by the judge subagents:
earnings-analysis/Companies/{TICKER}/manifests/{QUARTER}/judge/{TASK_ID}.tsv
Each file contains a single 12-field line (no header). Do not use TaskGet for news results.
Note: Each date has exactly one JUDGE task with the final validated result. BZ/WEB/PPX tasks contain intermediate results.
GUIDANCE RESULTS:
When all TARGET guidance tasks (GX-*) are completed, collect results from per-task files written by the guidance subagents:
earnings-analysis/Companies/{TICKER}/manifests/{QUARTER}/gx/{TASK_ID}.tsv
Each file contains newline-delimited guidance entries in the 18-field format below, or NO_GUIDANCE|{source_type}|{source_key}, or ERROR|.... Do not use TaskGet for guidance.
period_type|fiscal_year|fiscal_quarter|segment|metric|low|mid|high|unit|basis|derivation|qualitative|source_type|source_id|source_key|given_date|section|quote
Field definitions:
period_type: quarter, annual, half, or long-rangefiscal_year: e.g., 2025fiscal_quarter: 1, 2, 3, 4, or . for annualsegment: Total (default), or specific segment like Services, iPhone, AWSmetric: Normalized name like Revenue, EPS, Gross Marginlow, mid, high: Numbers or . for qualitative guidanceunit: %, USD, B USD, % YoY, etc.basis: GAAP, non-GAAP, as-reported, etc.derivation: explicit, calculated (mid derived), point, or implied (qualitative only)qualitative: Non-numeric guidance text (e.g., "double digits") or .source_type, source_id, source_key: Source identificationgiven_date: When guidance was issued (YYYY-MM-DD)section: Location in source (e.g., "CFO prepared remarks", "Outlook section")quote: Exact text with pipes replaced by ¦Or NO_GUIDANCE|{source_type}|{source_key} if no guidance found in that source.
Note: Guidance tasks have no dependencies and complete independently of news tasks.
Phase 4.5: Validation gate (MANDATORY, before Step 3b)
Fresh session rule (context saver): Run Phase 4.5 + saving results in a new session using the same CLAUDE_CODE_TASK_LIST_ID. This avoids carrying the full spawn-phase context into validation.
Load the TARGET manifest from:
earnings-analysis/Companies/{TICKER}/manifests/{QUARTER}.json
Validation rules:
news.judge_tasks ID:
earnings-analysis/Companies/{TICKER}/manifests/{QUARTER}/judge/{TASK_ID}.tsvguidance.tasks ID:
earnings-analysis/Companies/{TICKER}/manifests/{QUARTER}/gx/{TASK_ID}.tsvNO_GUIDANCE| → skipERROR| → invalid (retry)Counting rule (no headers):
gx/*.tsv and judge/*.tsv) never include headers.*.tsv files and compare to manifest IDs.*.tsv files not referenced by the manifest (do not treat them as errors).Hard stop rule (fail-closed):
guidance.csv, .ok, or processed caches.Best-effort mode (deterministic):
earnings-analysis/Companies/{TICKER}/manifests/{QUARTER}.retry.json
Format: {"failed":[{"id":"123","reason":"invalid_format"}, ...]}Only create the .ok marker when there are zero failed tasks. Processed CSV updates require the .ok marker; the retry file never unlocks processing.
Use the Write tool (not Bash redirection) for .ok, processed CSVs, and per-task outputs (gx/*.tsv, judge/*.tsv) so hooks can enforce guards.
If no tasks are missing/invalid:
earnings-analysis/Companies/{TICKER}/manifests/{QUARTER}.ok
Content must be exactly validated on a single line (no timestamp).
(This marker is required to unlock processed CSV updates.)NEWS RESULTS:
Write all valid rows. If retry file exists, do NOT update processed cache.
Source of truth: per-task files in earnings-analysis/Companies/{TICKER}/manifests/{QUARTER}/judge/.
For each judge task ID in the manifest, read {TASK_ID}.tsv and append the 12-field line.
earnings-analysis/Companies/{TICKER}/earnings-analysis/Companies/{TICKER}/news.csv:
quarter column with value {CURR.fiscal_quarter}_FY{CURR.fiscal_year} (e.g., Q1_FY2024)quarter|date|news_id|driver|attr_confidence|pred_confidence|daily_stock|daily_adj|market_session|source|external_research|source_pub_date|judge_notesnews.expected_judge=0, do not append any rows.news.csv exists → leave it unchanged. If it does not exist → create header only using the Write tool (never overwrite existing rows).earnings-analysis/news_processed.csv:
ticker|quarter|fiscal_year|processed_date{TICKER}|{CURR.fiscal_quarter}|FY{CURR.fiscal_year}|{today YYYY-MM-DD}GUIDANCE RESULTS:
Write all valid rows. If retry file exists, do NOT update processed cache.
Source of truth: per-task files in earnings-analysis/Companies/{TICKER}/manifests/{QUARTER}/gx/.
For each guidance task ID in the manifest, read {TASK_ID}.tsv and append any valid lines (skip NO_GUIDANCE|...).
4. Append TARGET guidance to earnings-analysis/Companies/{TICKER}/guidance.csv:
quarter column with value {CURR.fiscal_quarter}_FY{CURR.fiscal_year}quarter|period_type|fiscal_year|fiscal_quarter|segment|metric|low|mid|high|unit|basis|derivation|qualitative|source_type|source_id|source_key|given_date|section|quotefiscal_quarter here is numeric (1-4) from guidance-extract; do not convert to Q1 formatNO_GUIDANCEearnings-analysis/guidance_processed.csv:
ticker|quarter|fiscal_year|processed_date{TICKER}|{CURR.fiscal_quarter}|FY{CURR.fiscal_year}|{today YYYY-MM-DD}Run only if:
{TICKER} results for TARGET were saved, and{TICKER}/manifests/{QUARTER}.ok exists, andEnsure files exist (header‑only if missing):
earnings-analysis/Companies/{TICKER}/news.csv
quarter|date|news_id|driver|attr_confidence|pred_confidence|daily_stock|daily_adj|market_session|source|external_research|source_pub_date|judge_notesearnings-analysis/Companies/{TICKER}/guidance.csv
quarter|period_type|fiscal_year|fiscal_quarter|segment|metric|low|mid|high|unit|basis|derivation|qualitative|source_type|source_id|source_key|given_date|section|quoteCall prediction with the accession and pipeline inputs:
/earnings-prediction {CURR.accession} ticker={TICKER} filing_datetime="{CURR.date}" quarter_label={CURR.fiscal_quarter}_FY{CURR.fiscal_year}
The prediction skill will verify metadata against these inputs and enforce PIT filtering.
After prediction completes successfully, update:
earnings-analysis/prediction_processed.csv
ticker|quarter|fiscal_year|processed_date|accession{TICKER}|{CURR.fiscal_quarter}|FY{CURR.fiscal_year}|{today YYYY-MM-DD}|{CURR.accession}Next quarter is handled by re-running the same TARGET flow on the next uncached row.
=== EARNINGS ORCHESTRATOR: {TICKER} ===
--- TARGET QUARTER ---
TARGET: {TARGET}
Date: {CURR_DATE} | FY{CURR.fiscal_year} {CURR.fiscal_quarter} | adj={CURR.daily_adj}% | vol={CURR.trailing_vol}% ({CURR.vol_days}d) {CURR.vol_status}
--- NEWS ANALYSIS ({START} to {END}) ---
Filter: |stock|>=4%, |adj|>=max(2×{CURR.trailing_vol}%,3%)
Significant dates: {count}
date|news_id|driver|attr_confidence|pred_confidence|daily_stock|daily_adj|market_session|source|external_research|source_pub_date|judge_notes
...
--- GUIDANCE EXTRACTION ---
Content sources processed: {total_sources}
- exhibits: {exhibit_count}
- sections: {section_count}
- financial_stmt: {financial_stmt_count}
- xbrl: {xbrl_count}
- transcripts: {transcript_count}
- news: {news_count}
Guidance entries found: {guidance_count}
quarter|period_type|fiscal_year|fiscal_quarter|segment|metric|low|mid|high|unit|basis|derivation|qualitative|source_type|source_id|source_key|given_date|section|quote
...
--- NEWS SUMMARY ---
Total dates analyzed: {N}
Explained by Benzinga: {B}
Explained by WebSearch: {W}
Explained by Perplexity: {P}
Still unknown (confidence=0): {U}
Validated by Judge: {J}
--- GUIDANCE SUMMARY ---
Total content sources processed: {total_sources}
- exhibits: {exhibit_count}
- sections: {section_count}
- financial_stmt: {financial_stmt_count}
- xbrl: {xbrl_count}
- transcripts: {transcript_count}
- news: {news_count}
Total guidance entries found: {total_guidance}
=== COMPLETE ===
echo "=== ORCHESTRATOR_COMPLETE {TICKER} $(date '+%Y-%m-%d %H:%M:%S') ==="
This command triggers the PostToolUse hook which automatically runs:
build-news-thinking.py --ticker {TICKER}build-guidance-thinking.py --ticker {TICKER}Thinking files appear in Obsidian at Companies/{TICKER}/thinking/{QUARTER}/ without explicit script calls.
run_in_background: true. Wait for each batch to complete before proceeding. This is critical for proper result collection.run_in_background: true.fiscal_year as FY{YYYY} (e.g., FY2023), never plain year.ok exists (no retry file)Script errors return structured format: ERROR|CODE|MESSAGE|HINT
If any script returns ERROR:
Input: AAPL
Flow: