# Round 14 — Tower J13-J17 · 4 Writers + Editor

**Date**: 2026-04-30
**Time**: 1.5h budget
**Status**: ✅ COMPLETE
**Round Type**: Tower Floors

---

## 🎯 הקומות

| # | Station | תפקיד | Latency |
|---|---|---|---|
| **J13** | News Writer | כתיבה קלאסית, hard news | <8s |
| **J14** | Feature Writer | כתבת רקע, סיפור מורחב | <12s |
| **J15** | Op-Ed Writer | פרשנות, ניתוח | <10s |
| **J16** | Brief Writer | summary, 100-200 מילים | <4s |
| **J17** | Editor | הגהה, dedup, dietr style | <3s |

זאת הקומה הכי **יקרה** במגדל. כל writing run ~$0.005-0.015.

---

## 📰 J13 · News Writer (Hard News)

### Prompt template
```
System:
You are a Hebrew news writer for {tenant.name}.
Style: {tenant.brand_voice}  // e.g. "Concise, factual, RTL-first"
Constraints:
- Inverted pyramid (most important first)
- Lead = 25-35 words max
- Average sentence: 18-22 words
- Active voice 80%+
- Quote attribution after first mention
- No editorializing

5W context:
{w5_json}

Vector context (5 most relevant):
{context_cards}

Tone analysis (source):
{tone_json}

FactCheck flags:
{factcheck_flags}

Output: Article in Hebrew, 350-500 words.
Format: { headline, subheadline, lead, body_paragraphs[], pull_quote }
```

### Why structured output (object)?
ה-renderer ב-frontend צריך **לדעת מה headline ומה lead** כדי לרנדר באופן שונה (ArticleHero למשל).

### Streaming
**Token-by-token** דרך `chunk` event:
```json
{"version":"v0.9","updateDataModel":{"surfaceId":"article-output","path":"/article/text","value":"אמש,"}}
{"version":"v0.9","updateDataModel":{"surfaceId":"article-output","path":"/article/text","value":"אמש, בשעות הערב,"}}
// ... 1500+ chunks
```

ה-`Markdown` component (Round 5) קורא מ-`/article/text` ומציג typewriter effect — בדיוק כמו ChatGPT.

### Cost
- Input: 5W (~500) + context (~2000) + tone (~150) + flags (~200) = **~3,000 tokens**
- Output: ~600 tokens (350-500 words Hebrew)
- Cost (Gemini 2.5 Flash): **~$0.0045**

---

## 📚 J14 · Feature Writer

### תפקיד
כתבת **רקע** מורחבת. במקום 350 מילים → **800-1,500**. מערב הקשר היסטורי, ראיונות, תיאור צבעוני.

### Differences from J13
- **Length**: 800-1,500 words
- **Structure**: 5-act narrative (intro → context → details → analysis → conclusion)
- **Tone**: descriptive, scene-setting
- **Quotes**: encouraged, even if simulated
- **Subheadings**: required every ~250 words

### Cost
- Input: same as J13 + extended context
- Output: ~1,500 tokens
- **Cost: ~$0.011**

---

## 💬 J15 · Op-Ed Writer

### תפקיד
פרשנות / ניתוח. שונה מ-news:
- Personal voice OK
- Argumentative
- Evidence-based opinion
- Counter-arguments accepted

### Cost: ~$0.008

---

## ⚡ J16 · Brief Writer (Summary)

### תפקיד
תקציר 100-200 מילים. **most-used station** (90% of flows). הכי זול.

### Cost: ~$0.0015

---

## ✏️ J17 · Editor

### תפקיד
האחרון בpipeline של writing:
1. **Style consistency**: מאחד tone ב-paragraphs
2. **Repetition detection**: מסיר חזרות
3. **Brand voice alignment**: מיישם tenant voice
4. **Length adjustment**: מתאים לאורך target

### Implementation
**Single Gemini Flash call** עם article + style guide. Output: edited article.

### Cost: ~$0.002

---

## 🎯 ההכרעות הקריטיות

### 1. למה 4 writers נפרדים ולא writer יחיד?

3 סיבות:
- **Cost**: J16 (Brief) הכי שכיח. אם כל message עובר דרך J14 (Feature) — עלות x10.
- **Latency**: J16 = 4s. J14 = 12s. אם user רוצה brief — לא לחכות 12s.
- **Specialization**: prompt לFeature שונה מהותית מל-News. fine-tuning per-style.

### 2. Selection logic

```python
def select_writer(triage, desk, user_request):
    if user_request.format == "brief":      return "J16"
    if triage.urgency == "breaking":        return "J16"  # speed
    if desk in ("entertainment","social"):  return "J14"  # feature-friendly
    if desk == "politics" and tone == "promotional": return "J15"  # op-ed needed
    return "J13"  # default news writer
```

### 3. Editor אופציונלי?

Yes! ב-`config.tenant`:
- Maariv → editor required (high quality bar)
- Walla → editor optional (speed prioritized)
- Internal newsroom → editor required

---

## ✅ Closure
✅ **Round 14 closed. 17/54 floors documented.**
