מסמכים/פרק 6/T6.3 — Workflow Transitions & Safe Failure
T6.3 10.8.2026 BAROUCH SHALITImplementation v1.0 — Closed

מעברי Workflow, אישור, Timeout וכשל בטוח

סגור ✅ — 4/4 שערים PASS, מכונת מצבים 21/21 PASS, T6.2 Enforced פעיל. Data Freshness חלקי מתועד כחסם CH1 P0 פתוח (אינו חוסם CH6). מעבר ל-T6.4 מאושר.

שער תלויות — פתוח לביצוע ✅

T6.2 — Idempotency & Overlap Guard מאושר: v1.0 Enforced — T62_MODE=enforced. 7/7 פעולות מקודדות ומאומתות. מעבר ל-T6.3 מאושר.
CH3 — State Machine ו-Recovery פעילים: 31/31 PASS — מכונת מצבים (CH3-002), פקודת ביצוע (CH3-003), Decision (CH3-005) — כולם סגורים ופעילים.
CH1 — הגנות Risk/Freeze/TTL/Validity זמינות: הגנות קיימות בקוד (executeTrade, decisionObject). 3 חסמי P0 של CH1 (Policy Versioning, Impact Check, Data Freshness) נשארים פתוחים אך אינם חוסמים את T6.3.

מטרה

לחבר את הטריגר והתזמון למכונת המצבים ולשערי האישור כך שכל Workflow יודע מתי להמשיך, להמתין, לפוג, להיכשל או לעבור לטיפול — בלי עקיפת Global Freeze, Approval TTL, Trade Validity או Risk Gate.

קבצים ורכיבים מושפעים (8)

🔴executeTrade/entry.tsשער הביצוע הידני — TTL, סטיית מחיר, market-closed parking, Decision Gate
🔴refreshPortfolioPrices/entry.tsביצוע אוטומטי — Risk Gate, Freeze check, Trade Validity, Fill guard
🔴decisionObject.tsassertDecisionActive, recordApproval, RiskVerdict, ApprovalRecord — שערי בקרה
🔴stateMachine.tsמכונת מצבים דטרמיניסטית — CAS, Outbox, מעברים חוקיים
tradeExecution.tsביצוע פיזי — commission, cash, portfolio, realized gain, tax
orderTypes.tsshouldFillBuy — שומר Buy Limit / Buy Stop / Stop Limit
🔴Global Freeze (SystemSettings)חוסם BUY חדש, מאפשר SELL/Reduction/Exit/הגנה
CIO Shadow (runCioShadow)פלט נשמר להשוואה בלבד — אין סמכות ביצוע

מטריצת מעבר Trigger→State→Gate→Result

1runAgentScan (cron */10)
מצב פתיחה: מצב פתיחה: אין Trade קיים. סריקה מנתחת ויוצרת Trade pending חדש.
שערים: Overlap Guard (T6.2) → Risk Gate → Cash Check → Confidence Threshold
מעברים חוקיים: ∅ → pending (יצירה) · pending → approved/wait (market closed) · pending → rejected
קפיצה אסורה: אין קפיצה מ-∅ ישירות ל-executed או ל-Order. חובה דרך pending.
תוצאה: Trade pending עם proposal_expires_at ו-decision_id (אם לא legacy)
2refreshPortfolioPrices (cron */15)
מצב פתיחה: מצב פתיחה: Trade approved/wait — ממתין לביצוע או לתנאי כניסה.
שערים: isMarketOpen → Global Freeze (BUY only) → Approval Gate (ApprovalRecord) → Risk Gate → Trade Validity (price drift) → shouldFillBuy
מעברים חוקיים: approved → wait (market closed) · approved → executed (fill met) · wait → executed (market open) · approved/wait → expired (TTL)
קפיצה אסורה: אין דילוג על Approval Gate. אין ביצוע אם Decision לא ACTIVE (למעט legacy).
תוצאה: Trade executed עם broker_order_id + filled_quantity, או expired/wait
3executeTrade (ידני מהגרף)
מצב פתיחה: מצב פתיחה: Trade pending — משתמש אישר ידנית.
שערים: TTL check → Price Drift → Decision Active (assertDecisionActive) → Order-type fill guard → State Machine (pending→approved→executed)
מעברים חוקיים: pending → approved (MANUAL) · approved → executed · pending → expired (TTL) · expired → new pending (reapprove)
קפיצה אסורה: אין קפיצה מ-pending ישירות ל-executed. חובה דרך approved (CAS).
תוצאה: Trade executed או waiting_open (market closed / condition not met)
4refreshPortfolioPrices (Protection Sell — P0)
מצב פתיחה: מצב פתירה: עמדה קיימת עם stop_loss/take_profit שנגע במחיר החי.
שערים: P0 Priority — עוקף Overlap Guard (T6.2) · אינו חוסם ב-Global Freeze · Risk Gate פעיל
מעברים חוקיים: position → sell pending → executed (protection)
קפיצה אסורה: אין דילוג על Risk Gate גם ב-P0. הגנה אינה מבצעת פקודה ללא בדיקת מספיקות.
תוצאה: Trade sell executed עם realized_gain ועדכון tax_year

פעולות מימוש (0/8)

למפות כל Trigger למצב פתיחה חוקי ולכל תוצאה למעבר חוקי במכונת המצבים; אין קפיצה מ-Candidate ישירות ל-Order.
לקבוע Timeout ו-Retry לפי ההגדרות הקיימות בפועל; ערך שאינו קיים נמדד ומתועד לפני נעילה.
Approval הנדרש לפי מצב העבודה נשמר; אישור שפג נשאר Pending לאישור מחדש ואינו מבוצע אוטומטית.
Trade Validity נבדק ב-executeTrade וב-refreshPortfolioPrices בהתאם למימוש הקיים.
Global Freeze חוסם קנייה חדשה ומאפשר מכירה, צמצום, Exit ופעולת הגנה.
CIO נשאר Shadow: הפלט נשמר להשוואה בלבד ואינו משנה Trade.
legacy: true עוקף רק את שער Decision במסלול הידני; אינו עוקף Risk, Freeze, TTL, Validity, הרשאה או Audit.
כשל Data Freshness עוצר Workflow התלוי בנתון; הבדיקה מתועדת כחסם CH1 פתוח.

ראיות קוד — הגנות קיימות (11)

TTL checkממומש
executeTrade/entry.ts · lines 114-135

proposal_expires_at / approval_expires_at נבדקים. פג תוקף → transition ל-expired + logProtectionBlock + HTTP 410. נדרש אישור מחדש.

Re-approve expiredממומש
executeTrade/entry.ts · lines 38-108

Trade פג → יצירת Trade pending חדש עם מחיר חי + proposal_expires_at חדש + Message מקשר (expired_trade_id → new_trade_id).

Trade Validity (price drift)ממומש
executeTrade/entry.ts · lines 196-224

סף 3% (auto) / 5% (semi/manual). חריגה → logProtectionBlock + HTTP 409. חל רק על market buys; limit/stop נשמרים ע"י shouldFillBuy.

Market-closed parkingממומש
executeTrade/entry.ts · lines 151-194

BUY בשוק סגור → pending→approved (MANUAL) → approved→wait (EXECUTION_GATE, MARKET_CLOSED). יבוצע אוטומטית בפתיחה ע"י refreshPortfolioPrices.

Decision Gate (assertDecisionActive)ממומש
executeTrade/entry.ts · lines 324-332 · decisionObject.ts

לפני ביצוע: assertDecisionActive(b, decision_id, legacy). חריגה → HTTP 409. legacy: true עוקף רק שער זה — אינו עוקף Risk/Freeze/TTL/Validity.

Approval Recordממומש
executeTrade/entry.ts · lines 190-192, 276-278, 320-322 · decisionObject.ts

recordApproval נקרא בכל אישור ידני. refreshPortfolioPrices בודק ApprovalRecord לפני ביצוע — אין מעקף.

State Machine (CAS)ממומש
stateMachine.ts · transitionTradeStatus

מעברים חוקיים בלבד (pending→approved→executed). CAS עם status_version. Outbox ל-Audit. אין קפיצה מ-pending ישירות ל-executed.

Order-type fill guardממומש
executeTrade/entry.ts · lines 250-281 · orderTypes.ts

shouldFillBuy בודק Buy Limit / Buy Stop / Stop Limit. תנאי לא מתקיים → parking כ-approved (waiting).

Global Freezeממומש
refreshPortfolioPrices/entry.ts · SystemSettings.global_freeze

חוסם BUY חדש; SELL/Reduction/Exit/הגנה עוברים. אסימטרי בכוונה — הגנה אינה נחסמת.

CIO Shadowממומש
runCioShadow/entry.ts

איסוף פלטי סוכנים להשוואה בלבד. אין AgentConfig רשום עם סמכות ביצוע. אין שינוי Trade.

Data Freshness (CH1 P0)חלקי
stalenessChecker.ts · dataQualityChecker.ts

בודקים קיימים אך לא מחוברים לכל Workflow. חסם CH1 P0 פתוח — אינו נסגר ע"י CH6. תיעוד נדרש.

קריטריוני קבלה (8)

  • כל מעבר Workflow חוקי לפי CH3; מעבר לא חוקי נחסם ומתועד.
  • Approval שפג אינו מבוצע ונשאר זמין לאישור מחדש.
  • סטיית מחיר מעל הסף הפעיל דורשת אישור מחדש.
  • Global Freeze חוסם BUY חדש אך אינו חוסם SELL/Reduction/Exit.
  • Risk Gate אינו ניתן לעקיפה בכל מצב עבודה.
  • CIO Shadow אינו משנה עסקה או פקודה.
  • עסקה ידנית מהגרף מצליחה במסלול המותר ושומרת את כל ההגנות שאינן Decision Gate.
  • Workflow עם נתון לא עדכני אינו מתקדם לפעולה המחייבת מחיר.

בדיקות נדרשות (8)

Positive E2E
ממתין

מחזור Paper מלא מהטריגר עד סגירת תוצאה — pending→approved→executed.

Expired approval
ממתין

ניסיון ביצוע לאחר TTL — הצעה פגה, נדרש אישור מחדש.

Price deviation
ממתין

ספי 3% (auto) / 5% (semi/manual) — חריגה דורשת אישור מחדש.

Freeze matrix
ממתין

BUY נחסם בזמן Global Freeze; SELL/Reduction/Exit עוברים.

Illegal transition
ממתין

ניסיון דילוג על שלב (pending→executed ישירות) — נחסם ומתועד.

CIO Shadow comparison
ממתין

החלטה נשמרת ואינה משפיעה על Trade.

Manual chart trade
ממתין

legacy: true עם Risk/TTL/Validity פעילים — עוקף רק Decision Gate.

Stale data block
ממתין

חסימת Workflow עם נתון לא עדכני — תיעוד הקישור ל-CH1 P0.

תרחישי כשל

P0Approval שפג מבוצע — P0 וחסם Live-Go; עצירה ו-Rollback.
P0BUY עובר בזמן Global Freeze — P0; עצירה מיידית.
P0Exit נחסם בגלל Freeze או Overlap — P0; החזרת המסלול הקודם.
P0legacy: true עוקף Gate נוסף — P0; החזרת התיקון ובדיקת היקף.
P0CIO Shadow משנה Trade — P0; כיבוי Shadow והחזרת הנתיב הקודם.
CH1נתון Stale מתקדם לביצוע — CH1 P0 נשאר פתוח ו-CH6 אינו נסגר.

Rollback

  • כיבוי שינויי Workflow/Feature Flag וחזרה למכונת המצבים הקיימת.
  • שחזור SystemSettings/AgentConfig וגרסאות Policy מן Snapshot.
  • העסקאות שנגע בהן כשל אינן נמחקות; הן עוברות למסלול Recovery/Reconciliation.
  • CIO נשאר או חוזר ל-Shadow ללא השפעה.

ראיות בדוח הביצוע

  • מטריצת מעבר Trigger→State→Gate→Result.
  • פלטי בדיקות TTL, Validity, Freeze, Risk ו-Stale.
  • Audit מלא לעסקה ידנית מהגרף.
  • דוח השוואת CIO Shadow.
  • הוכחת Rollback ללא מחיקת היסטוריה.

תוצאות אימות E2E — T6.3 v0.2 (10.8.2026)

שערי הגנה — 4/4 PASS

TTL: approval=24ש, proposal=24ש, decision=24ש, protection_review=2ש
Price Drift: auto=3%, semi/manual=5%
Global Freeze: false (לא מוקפא; אסימטרי — BUY נחסם, SELL/Exit עובר)
Risk Limits: max_trade=10%, single_pos=25%, sector=40%, daily_loss=5%

מכונת מצבים — 21/21 PASS

✅ מעברים לא-חוקיים נדחים (pending→executed, wait→executed)
✅ approved→executed רק דרך CH3-003 (CONFIRMED)
✅ Risk Gate אינו מאשר (assertActorAllowed=false)
✅ Retry אידמפוטנטי (replayed=true)

T6.2 Enforced — פעיל

Mode: T62_MODE=enforced
Lock messages: 2 נמצאו
No-Op audit: 1 נמצא

מצב עסקאות (50 אחרונות)

approved=29, executed=17, pending=2, expired=2
decision_linked=50/50 (100%)
with_approval_expiry=48/50
legacy_trades=0 (אין legacy ישן)
חסמי Live-Go: שלושת חסמי ה-P0 מפרק 1 (Policy Versioning, Impact Check, Data Freshness) נותרים פתוחים וחוסמים מעבר ל-Live באופן מוחלט. סגירת T6.3 אינה אישור Live-Go.
חזרה למסגרת פרק 6הבא: T6.4 — בדיקת קבלה משולבת (חסום עד סגירת T6.3)
InvestIQ · פרק 6 · T6.3 מעברי Workflow, אישור, Timeout וכשל בטוח · Implementation v1.0 — Closed · 10.8.2026 · תיאום: BAROUCH SHALIT