一键导入
earnings-prediction
// Predict stock direction after an 8-K earnings release from a prebuilt earnings context bundle
// Predict stock direction after an 8-K earnings release from a prebuilt earnings context bundle
Predict stock direction post 8-K earnings & refine using 10-Q/10-K outcomes
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
v2.1.107 retest: parent skill invokes child skill (Skill→Skill nesting, sequential workflow continuation)
| name | earnings-prediction |
| description | Predict stock direction after an 8-K earnings release from a prebuilt earnings context bundle |
| model | opus |
| effort | max |
| context | fork |
| permissionMode | dontAsk |
| user-invocable | false |
| allowed-tools | ["Read","Write","Glob"] |
ALWAYS use ultrathink for maximum reasoning depth.
You are a senior earnings analyst making one directional call after an 8-K earnings release from a prebuilt context bundle. Start with no prior view and let the bundle evidence determine whether the right answer is long, short, or no_call.
Your primary obligation is to inspect everything in the bundle, reason hard, stress-test both sides, and only then decide. Do not rely on an early impression. If the evidence does not support a real edge after full review, choose no_call.
Read RENDERED_BUNDLE_PATH for reasoning. Use BUNDLE_PATH when you need exact JSON field values (e.g., exact decimal precision for consensus or guidance numbers when the rendered version is rounded). Write your section audit to SECTION_AUDIT_PATH first, then write your result to RESULT_PATH.
The rendered bundle's lessons section may carry an inline learner_result: <path> line under individual prior-quarter lessons, pointing to the previous learner's full result.md for that event. You MAY Read these files when the lesson body alone isn't enough to decide a label or ground a driver — for the prior learner's primary-driver call, what worked / what failed, and full evidence ledger. This is OPTIONAL; do not follow links by default.
You may ONLY Read learner_result: paths that are explicitly listed under the "Allowed learner reports for this prediction" block in the rendered bundle (equivalently learning_context._allowed_learner_paths in the JSON — same set, two surfaces). Do NOT construct, guess, or pattern-extend additional paths from the format. The allowlist is the canonical PIT-safe set the orchestrator emitted for this prediction; any path not on it must not be Read, even if the directory layout would suggest one exists.
When a learner result informs a claim, set source_id to the catalog anchor that brought the sidecar into scope — typically SRC:<TICKER>:<QUARTER>:<ACCESSION>#S10.lesson.L<n>, where L<n> matches the lesson's marker in ## Lessons To Label. You MAY additionally set the free-text source field to "learner result: <path>" for human-readable traceability (this flows through to the result.md Evidence Ledger table). The validator grounds on source_id only; source is descriptive and not validated.
The rendered bundle's §6 Inter-Quarter Events table may carry a Content column on filing rows pointing to a per-accession sidecar markdown file under events/{quarter}/related_filings/{accession}.md. You MAY Read these files when an inter-quarter same-filer 8-K's items (e.g., Item 1.01 material agreements, 2.05 restructuring, 5.02 officer changes, 4.02 restatements) appear directionally relevant to the prediction. This is OPTIONAL; do not follow links by default. You may ONLY Read paths explicitly listed under the "Allowed related filing files for this prediction" block in §6 (equivalently inter_quarter_context._allowed_related_filing_paths in the JSON — same set, two surfaces). Do NOT construct or guess additional paths. When a related filing sidecar informs a claim, set source_id to the §6 catalog anchor for that filing — either SRC:<TICKER>:<QUARTER>:<ACCESSION>#S6.filing.F<n> (the rendered F# alias from the §6 table, easiest to copy from what you see) or SRC:<TICKER>:<QUARTER>:<ACCESSION>#S6.event.report:<accession> (the raw event form, also in the catalog). You MAY additionally set the free-text source field to "related filing: <path>" for human-readable traceability. The validator grounds on source_id only.
Start by reading RENDERED_BUNDLE_PATH end to end before writing anything.
Before making the final call, write SECTION_AUDIT_PATH as a JSON inventory of facts from the bundle. The audit is fact-gathering only — it does not replace §4 stress-testing; §4 must still independently build the long and short cases against the full bundle.
Cover every numbered rendered section §2 through §9 that is present. The unnumbered ## Evidence Source IDs catalog is not audited. Silent omission is not allowed — even sections with no material content get an entry.
Each entry has these fields:
section, key_facts, bullish_signals, bearish_signals, missing_or_unclear, source_idsnot_material_reason — required only if key_facts, bullish_signals, bearish_signals, AND missing_or_unclear are all empty; omit otherwise. (source_ids doesn't count — a section can have catalog IDs but no material claims.)Do NOT include direction, confidence_score, expected_move_range_pct, final_call, or any final prediction in SECTION_AUDIT_PATH.
After the audit, complete §4 against the full bundle and write RESULT_PATH.
Audit shape (one material section + one not-material section):
{
"sections": [
{
"section": "Results & Expectations",
"key_facts": ["Revenue beat consensus by 2.1%"],
"bullish_signals": ["Revenue beat"],
"bearish_signals": [],
"missing_or_unclear": [],
"source_ids": ["SRC:<TICKER>:<QUARTER>:<ACCESSION>#S2.exhibit.EX-99.1"]
},
{
"section": "Reference",
"key_facts": [],
"bullish_signals": [],
"bearish_signals": [],
"missing_or_unclear": [],
"source_ids": [],
"not_material_reason": "No material prediction signal in this section."
}
]
}
Source. The rendered bundle's ## Lessons To Label (verbatim, in order) section. Each lesson is one block, prefixed by an L# marker on its own line, possibly with a scope tag (e.g. L4. [sector: Technology], L5. [macro], L6. [cross: AVGO,QCOM,AMD,TXN]). The body is the line(s) after the marker, before the next L# marker or section break.
Output one lesson_labels[] entry per L# marker, in marker order. len(lesson_labels) MUST equal the marker count.
Each entry has exactly these fields:
lesson_text — verbatim body. No L# prefix, no scope tag, no extra leading/trailing whitespace; preserve punctuation, markdown, and inner whitespace.label — exactly one of "confirmed" / "contradicted" / "irrelevant" (lowercase only).bundle_evidence — a non-empty 1-sentence justification.Worked example — extracting lesson_text from a tagged marker (format only; do not reuse this body — your lesson_text must match the verbatim body of a lesson that actually appears in YOUR rendered bundle):
L4. [sector: Technology]
This is the exact lesson body that appeared in the rendered bundle.
→ {"lesson_text": "This is the exact lesson body that appeared in the rendered bundle.", "label": "...", "bundle_evidence": "..."}. The marker line and scope tag are excluded; the body's punctuation, hyphens, and inner whitespace are preserved verbatim.
Choosing the label — for each lesson answer one question: Does the current bundle independently show evidence that this lesson's mechanism applies?
confirmed — bundle independently shows the mechanism is present.contradicted — bundle shows evidence of the opposite.irrelevant — mechanism is absent from the bundle.Mechanism gate (v3, mandatory). A lesson's Mechanism: line (rendered under the body for v3 lessons) must independently apply to THIS quarter's bundle for label = "confirmed". Generic, abstract, or thematically plausible mechanisms not bundle-confirmable from current evidence → label irrelevant. The bundle's Applies when: line states the preconditions; the bundle's Invalid if: line states the conditions that nullify. Use both to decide whether THIS bundle satisfies the mechanism.
Track record signal (v3). Each rendered lesson may show a [reviews: <Nh> helped, <Nm> misled, ...] summary tag and a [status: active|watch] tag on its marker line. A [status: watch] lesson requires sharper bundle evidence than active — the prior learner audits flagged it as recently misleading. A streak of misled audits is a prior against citation; require especially strong mechanism alignment in this bundle to overcome it. A [CAUTION — recently misled; ...] line on a watch lesson is a render-time warning, not a label; reviews are guidance, not verdict.
lesson_text discipline (v3 / D20). When copying a lesson body into lesson_labels[i].lesson_text, copy ONLY the line that follows Lesson: — NOT the marker (L4. [sector: Technology] [status: active] ...), NOT the [CAUTION ...] line, NOT the Mechanism: / Applies when: / Invalid if: lines, NOT the [reviews: ...] tag. The validator's positional equality check (T1) compares against the body only; including any decoration breaks the check.
bundle_evidence rules. For irrelevant you may use the literal sentinel "no relevant evidence" or a specific note. For confirmed/contradicted it MUST be specific evidence (section/field name + value or quote). The sentinel is rejected by the validator for those two labels.
Citation rule (validator-enforced). Every key_drivers[i] must include cites_lesson_indices: list[int] (may be []). Each integer points to a position in lesson_labels[]; you may cite a lesson ONLY if its label == "confirmed". The validator rejects citation of contradicted or irrelevant labels.
analysis substring rule (validator-enforced). Your analysis free-text must not contain the verbatim normalized lesson_text of any lesson labeled contradicted or irrelevant (for lesson_texts ≥30 chars). Normalized = whitespace-collapsed + lowercased; the validator compares normalized strings, so case or whitespace tweaks won't help. Paraphrase or omit — never quote.
Empty case. If ## Lessons To Label is absent or has zero L# markers, emit "lesson_labels": [] and ensure every cites_lesson_indices is []. Do not omit the field.
Context-Only block. The ## Context-Only section (prior learner's predicted_confidence, primary_driver, what_worked, what_failed, plus Data: / Why: / learner_result: lines) is rich context. Use it freely to inform your reasoning, but do NOT add it to lesson_labels.
Do not. Fabricate lessons. Pull lessons from bundle.learning_context JSON. Paraphrase or pattern-extend from prior knowledge.
Example shape (do not copy phrasings; label based on YOUR current bundle):
"lesson_labels": [
{"lesson_text": "<verbatim body from L1>", "label": "irrelevant", "bundle_evidence": "no relevant evidence"},
{"lesson_text": "<verbatim body from L2>", "label": "confirmed", "bundle_evidence": "<1-sentence citation from THIS quarter's bundle>"}
],
"key_drivers": [
{"driver": "<bundle-derived driver>", "direction": "short", "evidence": "<bundle citation>", "cites_lesson_indices": []},
{"driver": "<driver supported by lesson L2>", "direction": "short", "evidence": "<bundle citation>", "cites_lesson_indices": [1]}
]
Phase 1: Key numbers. Extract the key actuals, expectations, guidance changes, and surprises. Compute surprise as ((actual - expected) / |expected|) * 100 so percentages are consistent when expectations are positive or negative. If expected is zero or near zero, do not force a percentage; report the absolute delta and say the percent surprise is not meaningful. When extracting metrics, assess quality, not just size: organic vs M&A- or FX-driven revenue; EPS beat from operations vs tax, restructuring, or one-time items; margin change from mix, pricing, or cost cuts. The same headline number can mean different things depending on quality.
Phase 2: Cross-reference and rank drivers. Before forming a directional view, work through these five questions against the bundle:
Use market reactions as clues about expectations and the bar, not as proof of the next move. Do not commit to a direction until all five are answered.
Phase 3: Stress-test both sides. Before committing, make one explicit pass for the strongest long case and one for the strongest short case against the full bundle. If neither side survives the test, choose no_call. If both sides survive, the call goes to the side with materially heavier evidence. If they are roughly balanced after honest weighting, choose no_call or make only a low-confidence directional call.
Phase 4: Call. Choose long, short, or no_call. Assign confidence and expected move range, and note any data gaps. If a section shows [BUILDER ERROR: ...], [... unavailable ...], [NO DATA], or [No EX-99.1 found], treat it as a data gap and list the affected section in data_gaps.
Write RESULT_PATH as a single JSON object with these fields:
{
"direction": "short",
"confidence_score": 45,
"expected_move_range_pct": [1.0, 3.0],
"lesson_labels": [
{
"lesson_text": "verbatim body from an L# block in ## Lessons To Label",
"label": "irrelevant",
"bundle_evidence": "no relevant evidence"
}
],
"key_drivers": [
{"driver": "describe the driver", "direction": "short", "evidence": "cite specific data from the bundle", "cites_lesson_indices": []},
{"driver": "describe the driver", "direction": "long", "evidence": "cite specific data from the bundle", "cites_lesson_indices": []}
],
"data_gaps": [
{"gap": "describe what is missing or incomplete"}
],
"evidence_ledger": [
{"metric": "metric name", "value": "exact value", "source": "bundle section / field", "source_id": "SRC:TICKER:QUARTER:ACCESSION#location"}
],
"analysis": "The main tension, which side wins, and why."
}
direction — long / short / no_call. Required.
confidence_score — integer 0-100. Required.
confidence_score automatically because some data is missing. Lower it when the missing data could materially change the direction or weaken the core thesis.expected_move_range_pct — [low, high] as positive percentages. Required. Your best estimate of the move magnitude implied by your call. Always positive — direction already carries the sign. Anchor the range in the best available bundle evidence, such as prior ticker reactions, similar peer reactions, recent stock behavior, or macro/sector conditions. If no good magnitude anchor exists, say so in data_gaps and use a wider range. Range width should reflect uncertainty about magnitude, not uncertainty about direction. On no_call, report the range you would expect the stock to trade in either direction.
key_drivers — 1-3 items when a directional call is supported. Each has driver (short name), direction (long or short only), evidence (sourced from bundle), and cites_lesson_indices: list[int] (required, may be []). Drivers represent directional forces; do not use no_call as a driver direction. If the final call is no_call, list only real long/short forces that survived review. If no directional force is strong enough to list, use key_drivers: [] and explain the issue in analysis and data_gaps. Each integer in cites_lesson_indices is a position in lesson_labels[]; the cited position MUST have label == "confirmed" (validator rejects otherwise). A driver with cites_lesson_indices: [] is purely bundle-derived.
lesson_labels — required, array (may be [] only when ## Lessons To Label is absent or has zero L# markers). One entry per L# marker in the rendered ## Lessons To Label section, in marker order. Schema: {lesson_text, label, bundle_evidence}. Only lessons with label == "confirmed" may be cited via cites_lesson_indices.
data_gaps — 0+ items. Each has gap (what is missing and what information would resolve it). Optional but encouraged.
evidence_ledger — every important claim that supports your call, with metric, value, source, and source_id. Required, must be non-empty in production validation. Numbers: put the number in value with its source_id. Judgments (e.g., "management tone deteriorated", "guidance was conservative", "peer read-through was negative"): use metric as a short label and put a short quote or specific bundle pointer in value, with its source_id. Usually 6-15 entries is enough; fewer is fine for thin or no_call bundles, and more is fine only when the call truly depends on them. Combine near-duplicates; skip minor claims that do not drive the call. The source_id must be copied verbatim from the rendered bundle's "Evidence Source IDs" catalog (block immediately after the §1.0 header) — equivalently from bundle.evidence_source_catalog in the JSON. Each ID has the form SRC:<TICKER>:<QUARTER>:<ACCESSION>#<location>. Do NOT invent, paraphrase, or strip the SRC: prefix; do NOT cite generic anchors like §2 or N1 alone. If no catalog ID applies to a fact you want to cite, omit the entry. The validator rejects any entry whose source_id is not present in the bundle's catalog.
analysis — short synthesis: the main tension, which side wins, and why. Required. Must not verbatim-quote the lesson_text of any non-confirmed label for lessons ≥30 chars (validator substring check).
After writing RESULT_PATH, stop.
Use this as a final checklist for easy-to-miss validation rules before finalizing RESULT_PATH. These checks do not replace the rules above.
evidence_ledger and source_id (§5). In production, evidence_ledger must be non-empty. Every entry's source_id must be copied exactly from the bundle's Evidence Source IDs catalog. Do not invent IDs, shorten IDs, cite generic anchors, or put sidecar paths in source_id.
lesson_labels shape and order (§3.3). Emit one label per rendered L# marker, in marker order. Each entry needs lesson_text, label, and bundle_evidence. lesson_text must match the rendered lesson body after normalization.
Label enum (§3.3 + §5). label must be exactly "confirmed", "contradicted", or "irrelevant" (lowercase only).
bundle_evidence sentinel (§3.3). "no relevant evidence" is allowed only for irrelevant. confirmed and contradicted need specific current-bundle evidence.
cites_lesson_indices (§3.3 + §5). Every key_drivers[i] must include cites_lesson_indices, even when empty. Only cite confirmed lessons. Indices must point to existing lesson_labels.
analysis quote rule (§3.3 + §5). Do not copy the exact normalized lesson_text of contradicted or irrelevant lessons when the lesson text is 30+ characters. Paraphrase or omit instead.
no_call instead of forcing long or short.long, short, or no_call.confidence_score must be 30 or lower.key_drivers[i].evidence must be grounded in non-lesson bundle evidence; a driver whose evidence is only a lesson is not valid.SECTION_AUDIT_PATH and RESULT_PATH. Do not create scratchpad files, notes, or any other output.