מפרט טכני CH3 — Implementation Backlog
Version 0.2.2 — Review27.8.2026
סדר פעולה מוסכם
1.✓ להוציא גרסה מתוקנת של המסמך — Version 0.2.
2.✓ לאשר גרסה זו בכתב.
3.✓ מיפוי וניתוח של CH3-001 בלבד — ללא שינוי קוד: רשימת קבצים, סכמה נוכחית, תלויות, ובדיקת Message entity.
4.✓ לקבל רשימת קבצים, סכמה נוכחית, תלויות ותוכנית שינוי מפורטת.
4.1.✓ הכרעות Architect v0.2.2: 4 שאלות פתוחות + 2 הוראות מחייבות + הכרעת חפיפת Cron.
4.2.✓ אישור כתוב של מנגנון מניעת חפיפת Cron — בעל ביצוע יחיד (v0.2.2).
5.✓ ביצוע CH3-001 — מאושר לביצוע (כל התנאים התקבלו).
6.✓ עצור, בדיקה ודוח קבלה לפני CH3-002.
כללי עבודה
  • לא משנים החלטות פרקים 1–2 ללא גרסה חדשה ו-ADR.
  • כל נתיב ביצוע ממשיך לעבור דרך shared executeTrade וההגנות הקיימות (Freeze, pools, commission, tax).
  • כל שינוי נתונים (סכמה/סטטוסים) כולל Migration, שמירת Audit, ותאימות לרשומות קיימות.
  • אין לעבור ל-Live לפני סגירת כל משימות P0 וחסמי Go-Live.
  • כל משימה מסתיימת בבדיקת קבלה מתועדת — לא בהצהרת השלמה.
  • כל שינוי סכמה דורש אישור Architect מראש ובכתב.
  • עצירה לאחר כל בדיקה — אין מעבר למשימה הבאה לפני אישור בכתב.
מחוץ לתחום השינוי
  • שינויים ב-UI/UX מעבר לתצוגת הסטטוסים החדשים (CH3-002).
  • שינויים בלוגיקת חישוב עמלה, מס, או PnL.
  • הוספת ברוקר חי (Live) — כל ה-scope הוא Paper Trading.
  • שינויים בישויות Portfolio, Alert, Message מעבר לשדות Audit שיוגדרו (CH3-001).
  • שינויים ב-workflow scheduling.
  • שינויים בלוגיקת ה-LLM Prompt עצמה.
תוכנית Rollback וגיבוי
  • לפני כל התחלת משימה: snapshot של כל הקבצים המושפעים נשמר ב-Git commit נפרד.
  • ב-Base44: לבקש Diff לפני ואחרי כל שינוי.
  • נקודת שחזור: ה-commit לפני תחילת CH3-001 הוא נקודת החזרה ל-v0.1.
  • Migration: כל סקריפט Migration הוא הפיך — נשמר סקריפט rollback מקביל לפני הרצה.
  • אם בדיקת קבלה נכשלת: rollback מיידי לנקודת השחזור, תיעוד הכשלון, לא ממשיכים.
CH3-001 — הפרדת Orchestrator מה-CIO ומה-LLM
P0Go-Live Blocker
המצב הקיים

refreshPortfolioPrices (entry.ts, ~550 שורות) מבצע הכל בפונקציה אחת: רענון מחירים, אימות תפוגה, ביצוע קניות בהמתנה, מחיקת holdings שנמכרו, migration ILS, stop-loss/take-profit, Portfolio Risk Agent (InvokeLLM), התייעצויות מוגנות, ו-auto-sell. runAgentScan (entry.ts, ~600 שורות) מבצע ניתוח LLM + יצירת עסקאות + ביצוע באותה ריצה.

בדיקת Message entity לפני הכרעת סכמה
שדה נדרש ל-Auditקיים?הערה
step_nameחסרשם השלב (PRICE_REFRESH / TRADE_VALIDITY / וכו׳) — ניתן לכלול ב-title
step_statusחסרstarted / completed / failed — ניתן לכלול ב-summary
actorקיים (source)source משמש כ-actor — מספיק
timestampקיים (created_date)created_date אוטומטי — מספיק
correlation_idחסרמזהה ריצה לשיוך כל שלבי ריצה אחת — נדרש הכרעה
הוכרע (מיפוי + אישור Architect, v0.2.2): אפשרי ללא שינוי סכמה — קידוד בשדות קיימים (title/source/severity). ⚠ תיעוד תפעולי זמני בלבד — לא פתרון ה-Audit הסופי של המערכת. שמירת 30 יום מספיקה לבדיקת CH3-001 ותחקור קצר; פתרון שימור קבוע ייסגר לפני Live (ADR נפרד, מחוץ ל-CH3-001).
פעולות
  • פיצול refreshPortfolioPrices לשלבים דטרמיניסטיים נפרדים המפיקים אירוע (step event) לכל שלב.
  • runAgentScan ו-InvokeLLM יקבלו משימה מובנית ויחזירו Structured Output בלבד — ללא החלטות Retry/Timeout/סטטוס.
  • Risk Gate, Approval, Trade Validity ו-Execution יופעלו כשלבים נפרדים ומתועדים.
  • לפני יצירת shared/auditSteps.ts: לבדוק תחילה אם Message entity מסוגל לשמור את כל שדות ה-Audit הנדרשים. רק אם חסרים שדות — לשקול שינוי סכמה.
ארכיטקטורת יעד — 6 שלבים (שלב 3 בלבד = LLM)
שלבתיאורדטרמיניסטי
1. PRICE_REFRESHשירות דטרמיניסטי: fetchQuote לכל symbol → עדכון current_price/value/pnl ב-Portfolio. ללא LLM.כן
2. TRADE_VALIDITYבודק pending trades מול מחיר חי: סטייה > threshold → סימון לא-תקף (אין ביצוע/ביטול).כן
3. CIO_SCANrunAgentScan: InvokeLLM מחזיר Structured Output בלבד {recommendation, confidence, reasoning}. אין יצירת Trade כאן.LLM בלבד
4. RISK_GATEבודק פלט סריקה מול: Freeze, cash pool, max_per_trade, exposure. החלטה דטרמיניסטית: אשר/דחה/המתן.כן
5. APPROVALauto → ממשיך; semi → pending עם approval_expires_at; manual → alert בלבד.כן
6. EXECUTIONקריאה יחידה ל-shared executeTrade (עם כל ההגנות הקיימות).כן
קבצים מושפעים
  • base44/functions/refreshPortfolioPrices/entry.ts — פיצול לשלבים + הסרת החלטות LLM
  • base44/functions/runAgentScan/entry.ts — הפיכה ל-CIO טהור: פלט Structured Output בלבד
  • base44/shared/orchestrator.ts (חדש) — רץ השלבים הדטרמיניסטי + תיעוד step events
  • base44/shared/auditSteps.ts (חדש) — כתיבת step events — ⚠ תלוי בהכרעת Message entity
Migration

אין שינוי סכמה מתוכנן. ⚠ תלוי בתוצאת בדיקת Message entity (ראה למעלה) — אם יידרש correlation_id תיידרש הכרעה נפרדת.

הכרעות Architect — v0.2.2
שאלה פתוחההכרעהסטטוס
evaluateProtectionStatus — היכן ישב?ניתוח/המלצה בלבד ב-CIO_SCAN (שלב 3). החסימה בפועל דטרמיניסטית ב-RISK_GATE (שלב 4).הוכרע
autoSellHolding / evaluateTakeProfit — מיקום?עוברים לשלב 6 (EXECUTION). פעולות מכירה, Stop והגנה מקבלות קדימות לפני קניות ופתיחת סיכון חדש בתוך השלב.הוכרע
תיעוד שלב שלא שינה דבר?כן — יתועד בסטטוס מפורש completed_no_action, כדי להבדיל "בוצע ללא פעולה" מ-"שלב שלא הופעל".הוכרע
השארת לוחות הזמנים הקיימים?מותנית במנגנון מניעת חפיפה ל-EXECUTION — ראה הכרעת חפיפת Cron למטה. ללא מנגנון: אין לאשר השארה.הוכרע
הוראות מחייבות
1.summary יישמר כ-JSON במבנה קבוע וגרסאי (schema_version), לא כטקסט חופשי.
{
  "schema_version": "1",
  "run_id": "string",
  "step": "PRICE_REFRESH|TRADE_VALIDITY|CIO_SCAN|RISK_GATE|APPROVAL|EXECUTION",
  "status": "started|completed|completed_no_action|failed",
  "actor": "string",
  "started_at": "iso",
  "ended_at": "iso|null",
  "trade_id": "string|null",
  "details": "object",
  "error": "string|null"
}
2.בדיקת קבלה חייבת להוכיח שליפה של כל 6 האירועים לפי runId בסדר הנכון. אם לא ניתן — הכרעת "ללא שינוי סכמה" נפתחת מחדש (יידרש שדה correlation_id ייעודי).
הכרעת חפיפת Cron — interim עד CH3-003
סיכון: שני ה-cron (*/10 סריקה, */15 רענון) נפגשים כל 30 דקות; אם שניהם יקראו ל-executeTrade → כפילות ביצוע ומירוץ על cash pools. נעילה רכה ב-Message ("busy marker") אינה אטומית ועלולה לאפשר לשתי ריצות לעבור יחד — אינה מקובלת.
מנגנון: בעל ביצוע יחיד זמני עד CH3-003 (ללא נעילה, ללא שינוי סכמה):
  • Continuous Agent Scan מבצע ניתוח (CIO_SCAN), Risk Gate ו-Approval בלבד — ואינו קורא ל-executeTrade כלל.
  • Portfolio Price Refresh הוא היחיד שרשאי להפעיל את שלב EXECUTION.
  • סדר פנימי ב-EXECUTION של Portfolio Price Refresh: תחילה מכירות הגנה (Stop / Take Profit / auto-sell), ולאחר מכן עסקאות קנייה מאושרות שעברו Trade Validity.
  • אין להשתמש בנעילה באמצעות Message. אין להסתמך על execution_state (CH3-003) שטרם יושם.
  • קניות שאושרו על-ידי ה-Scan נשמרות כ-approved וממתינות לריצת ה-Refresh הבאה, שתבצע אותן דרך executeTrade.
בדיקת קבלה: בדיקת הקבלה תפעיל את שני ה-Workflows בו-זמנית ותוכיח שלכל Trade קיימת קריאה אחת בלבד ל-executeTrade.
✓ מאושר על-ידי Architect (v0.2.2). לאחר אישור Base44 — CH3-001 מאושר לביצוע.
תנאי קבלה
  • ה-LLM אינו מחליט על Retry, Timeout או שינוי סטטוס תפעולי.
  • ניתן לזהות ב-Audit את תחילת וסיום כל שלב (step_start / step_end עם timestamp ו-actor).
  • שלב שלא שינה דבר מתועד בסטטוס completed_no_action (מבדיל מ"לא הופעל").
  • כשל בשלב אחד אינו מפעיל מחדש אוטומטית שלבים שכבר הושלמו.
  • summary נשמר כ-JSON גרסאי (schema_version) במבנה קבוע — לא טקסט חופשי.
  • בדיקת קבלה מוכיחה שליפה של כל 6 האירועים לפי runId בסדר הנכון. אם לא — "ללא שינוי סכמה" נפתח מחדש.
בדיקת קבלה: הרצת workflow ובדיקה שב-Message entity נכתבים step events לכל 6 השלבים, ה-LLM אינו מופיע בשום trace של החלטת Timeout/Retry, וניתן לקשר את כל האירועים של ריצה אחת.
CH3-002 — מכונת מצבים דטרמיניסטית
P0Go-Live Blocker
הפרדת שלושת המישורים (לפני שינוי סכמה)
מישורScopeערכיםנשמר ב-DB
מצב מחזור העבודה של ה-Orchestratorפנימי ל-backend בלבד — לא נשמר ב-DBINITIALIZING → PRICE_REFRESHED → VALIDITY_CHECKED → CIO_SCANNED → RISK_GATED → APPROVAL_SET → EXECUTION_DONEלא
הסטטוס העסקי של ה-TradeTrade.status — גלוי למשתמש ולכל הממשקיםpending → approved / rejected / WAIT / EXPIRED / ESCALATED_FOR_REVIEWכן
מצב פקודת הביצוע מול הברוקרTrade.execution_state — שדה נפרד, לשימוש פנימי + ReconciliationNOT_SENT → SENT → CONFIRMED / FAILED / RECONCILIATION_REQUIREDכן
סטטוסים קנוניים — כולם lowercase
שםחדש/קייםתיאורטרמינל
pendingקייםהצעה בהמתנה לאישורלא
approvedקייםמאושר לביצועלא
executedקייםבוצעכן
rejectedקייםנדחה ידנית על-ידי משתמשכן
waitחדשהמתנה לתנאי שוק (buy-limit/stop שלא התמלאו)לא
expiredחדשתוקף האישור פג — TTL או סטיית מחיר חריגהכן
escalated_for_reviewחדשהועבר לבדיקה אנושית (מניה מוגנת / סכסוך החלטה)לא
RECONCILIATION_REQUIRED הועבר ל-CH3-003 (execution_state בלבד — לא Trade.status).
מטריצת מעברים חוקיים
מ- (from)אל (to) — מותר
pendingapproved, rejected, expired, wait, escalated_for_review
waitapproved, expired, rejected
approvedexecuted, rejected, expired
escalated_for_reviewapproved, rejected
executed / rejected / expiredטרמינל
מעבר אל escalated_for_review: מגיע מ-pending בלבד (כלול בשורת pending).
פעולות
  • הפרדה מוחלטת בין שלושת המישורים לפני כל שינוי סכמה (ראה טבלת מישורים).
  • קביעת שמות קנוניים — כולם lowercase — לתאימות עם הקוד הקיים (pending, approved, executed, rejected, wait, expired, escalated_for_review).
  • הגדרת מטריצת מעברים חוקיים ב-shared/stateMachine.ts עם assertTransition().
  • חסימת מעבר ישיר pending → executed (חובת approved בינתיים).
  • תפוגה → expired (לא rejected). rejected שמור לדחייה ידנית בלבד.
  • מקור אמת יחיד להיסטוריה: Message Audit בלבד — ללא שדה status_history על Trade.
  • Migration מ-rejected ל-expired: רק כאשר קיימת ראיה ברורה (שדה approval_expires_at עבר). ללא ראיה → Trade נשאר rejected ומסומן לבדיקה ידנית.
שינוי סכמה — Trade ⚠ דורש אישור Architect
status enum מורחב מ-[pending, approved, executed, rejected] ל-[pending, approved, executed, rejected, wait, expired, escalated_for_review]. כולם lowercase.
שדה חדשסוגתיאור
expiration_stagestring | nullAPPROVAL_TTL_EXPIRED | PRICE_DEVIATION_EXCEEDED | MARKET_DATA_STALE — מסביר מדוע הרשומה עברה ל-expired
expiration_reasonstring | nullטקסט חופשי — נימוק מפורט לתחקור
Migration
  • Trade עם status=rejected + שדה approval_expires_at שעבר: → status=expired, expiration_stage=APPROVAL_TTL_EXPIRED.
  • Trade עם status=rejected + אין approval_expires_at: → נשאר rejected, מסומן ב-expiration_reason="pending_manual_review".
  • Migration חד-פעמי, הפיך — סקריפט rollback מוכן לפני הרצה.
  • Migration key: trade.id בלבד (לא symbol+created_date — עלול להתנגש).
קבצים מושפעים
  • base44/entities/Trade.jsonc — הרחבת enum + 2 שדות ⚠ דורש אישור Architect
  • base44/shared/stateMachine.ts (חדש) — מטריצת מעברים + assertTransition()
  • base44/shared/tradeExecution.ts — כל שינוי status עובר דרך assertTransition()
  • base44/functions/refreshPortfolioPrices/entry.ts — תפוגה כותבת expired + expiration_stage
  • src/pages/Trades.jsx + src/components/invest/Badges.jsx — תצוגת הסטטוסים החדשים
תנאי קבלה
  • מעבר לא-חוקי (למשל pending→executed) נדחה ומתועד ב-Message Audit.
  • תפוגת TTL → expired (לא rejected). rejected = דחייה ידנית בלבד.
  • אישור מחדש של רשומה שפגה (expired) יוצר רשומה חדשה ואינו פותח את הישנה.
  • escalated_for_review ניתן להשגה ממצב pending בלבד.
  • כל הסטטוסים במאגר הם lowercase — אין ערבוב.
בדיקת קבלה: ניסיון מעבר pending→executed נדחה; תפוגת TTL → expired עם expiration_stage; אישור מחדש של expired יוצר רשומה חדשה; escalated_for_review מגיע מ-pending.
CH3-003 — Idempotency, Retry ו-Reconciliation
P0Go-Live Blocker
המצב הקיים

אין שדה idempotency_key ב-Trade. יש dedup רך לפי חלון 15 דקות (symbol+side) — אינו חסין ל-timeout. executeTrade אינו מסמן מצב "לא ידוע". אין הפרדה בין "טרם נשלח" ל-"לא ידוע".

שלושת השלבים — כולם דטרמיניסטיים
שלבתיאורדטרמיניסטי
IDEMPOTENCY_GUARDלפני שליחת פקודה: בדיקת כפילות לפי idempotency_key. אם קיימת רשומה executed עם אותו key — עצור, החזר את הרשומה הקיימת ללא שליחה חוזרת.כן
RECONCILIATIONלפני כל Retry: בדיקת מצב הפקודה מול DB (execution_state). אם execution_state=RECONCILIATION_REQUIRED — עצור ואל תשלח מחדש עד לאישור ידני.כן
CAPITAL_RESERVATIONבעת שליחת פקודה: נעל הון מה-pool (reserved_capital). בעת אישור ביצוע: המר ל-debit. בעת כישלון: שחרר. מונע overdraft ב-timeout.כן
ערכי execution_state
ערךתיאור
NOT_SENTרשומה נוצרה אך פקודה טרם נשלחה לברוקר (pending שלא הגיע לביצוע)
SENTפקודה נשלחה, ממתינים לאישור
CONFIRMEDברוקר אישר ביצוע
FAILEDברוקר דחה — ניתן לנסות מחדש לאחר Reconciliation
RECONCILIATION_REQUIREDtimeout — מצב הפקודה לא ידוע. עצור ואל תשלח מחדש
UNKNOWN אינו בשימוש — NOT_SENT לטרם-שליחה, RECONCILIATION_REQUIRED לאחר-timeout.
פעולות
  • הקצאת idempotency_key לכל Execution Command (לא לרשומת Trade — לכל פקודת ביצוע שנשלחת).
  • execution_state=NOT_SENT לרשומות שנוצרו ולא נשלחו (pending/wait). UNKNOWN שמור ל-timeout בלבד.
  • אין Retry לפקודת ברוקר לפני בדיקת execution_state — RECONCILIATION_REQUIRED עוצר הכל.
  • שמירת reserved_capital בעת שליחה — משוחרר בהצלחה/כישלון בלבד.
  • Migration key: trade.id (לא symbol+created_date).
שינוי סכמה — Trade ⚠ דורש אישור Architect
שדה חדשסוגתיאור
idempotency_keystring | nullמזהה ייחודי לפקודת ביצוע — נוצר בעת שליחה לברוקר (לא בעת יצירת Trade). פורמט: legacy:<trade_id> לרשומות קיימות.
execution_statestringNOT_SENT | SENT | CONFIRMED | FAILED | RECONCILIATION_REQUIRED — מצב פקודת ביצוע מול ברוקר, נפרד מ-Trade.status
reserved_capitalnumber | nullהון שננעל לטובת הפקודה עד אישור/כישלון ביצוע
Migration
  • רשומות Trade עם status=executed: execution_state=CONFIRMED, idempotency_key=legacy:<trade_id>.
  • רשומות Trade עם status=pending/wait/approved: execution_state=NOT_SENT, idempotency_key=null.
  • רשומות Trade עם status=rejected/expired: execution_state=FAILED, idempotency_key=null.
  • Migration key: trade.id בלבד — לא symbol+created_date (מונע התנגשויות).
  • סקריפט rollback מוכן לפני הרצה.
קבצים מושפעים
  • base44/entities/Trade.jsonc — 3 שדות חדשים ⚠ דורש אישור Architect
  • base44/shared/idempotency.ts (חדש) — generateKey() + checkDuplicate() + reserveCapital() / releaseCapital()
  • base44/shared/tradeExecution.ts — עטיפת ביצוע ב-idempotency guard + reconciliation
  • base44/functions/refreshPortfolioPrices/entry.ts — אין Retry ללא בדיקת execution_state
  • base44/functions/runAgentScan/entry.ts — הגדרת idempotency_key בעת שליחת פקודה
תנאי קבלה
  • אותו idempotency_key אינו יכול ליצור שתי הוראות ביצוע (Double Order מנוע).
  • Timeout → execution_state=RECONCILIATION_REQUIRED (לא שליחה חוזרת).
  • רשומת pending שלא נשלחה: execution_state=NOT_SENT (לא UNKNOWN).
  • בדיקת קצה מוכיחה שאין Double Order בתרחיש timeout מלאכותי.
בדיקת קבלה: הזרקת timeout מלאכותית בביצוע → execution_state=RECONCILIATION_REQUIRED, reserved_capital נשמר, אין פקודה כפולה. בדיקה שרשומת pending חדשה מקבלת NOT_SENT (לא UNKNOWN).
סיכום Migration ואישורים
משימהשינוי סכמהסיכוןאישור נדרשהערות
CH3-001תלוי בדיקת Message entityנמוךייתכן שנדרש (להכרעה)בדיקת entity לפני הכרעה
CH3-002Trade.status enum + 2 שדותבינונינדרש ArchitectMigration מ-rejected ל-expired רק עם ראיה
CH3-0033 שדות חדשים ב-Tradeבינונינדרש ArchitectMigration key: trade.id בלבד
InvestIQ CH3 Implementation Backlog v0.2.2 — 27.8.2026 | ממתין לאישור בכתב לפני ביצוע