CH4-001 · מיפוי As-Is ונעילת זהויות הסוכנים
גרסה 1.0 · 8.8.2026 · P0 · המשימה הראשונה — Approved for Implementation
✅ Approved for Implementation — Version 1.0
גרסה 1.0 — מפרט יישום סופי ומאושר. כל הערות הבטיחות נסגרו (9 תיקוני סקירה היסטוריים): התדירות האפקטיבית כלולה ב-config_hash; התרעות סיכון ממשיכות לפעול תמיד; שינוי entry_point מחייב migration_ref/ADR מאושר; AgentSnapshot הוא Append-Only ונבדק גם בניסיון Update/Delete; יציאות, מכירות והגנות P0 אינן נחסמות במקרה כשל Identity. הערת ביצוע מחייבת: effective_schedule_signature חייב להתווסף בפועל ל-AgentConfig (סעיף 9), כפי שמפורט ברשימות הקבצים והשלבים. לאחר הביצוע יש להחזיר דוח ביצוע עם תוצאות הבדיקות, Snapshot לפני ואחרי וראיות Rollback. לא עוברים ל-CH4-002 לפני אישור הדוח.
⚠️ הערת ביצוע מחייבת — effective_schedule_signature ב-AgentConfig
השדה effective_schedule_signature חייב להתווסף בפועל לישות AgentConfig (סעיף 9, רשימת קבצים מושפעים, וסדר ביצוע שלב 2). הוא נגזר מהקוד (AGENT_INTERVAL_MINUTES + MARKET_HOURS_TYPES) ונשמר כחלק מ-config_hash. ללא שדה זה, config_hash אינו כולל את התדירות האפקטיבית המלאה (interval_minutes + market_hours_policy), ונעילת התצורה אינה שלמה.
| הערה | נושא | תיקון |
|---|---|---|
| #1 (v0.2) | agent_id חסר בטבלת Baseline | agent_id נוסף לטבלה ולנעילת הזהות הקבועה. מחיקה ויצירה מחדש באותו שם אינן עוברות — agent_id שונה מפיק hash שונה. |
| #2 (v0.2) | הפרדת זהות קבועה מתצורה תפעולית | זהות קבועה (agent_id, name, type, region, market) → שינוי מחייב Migration/ADR. תצורה תפעולית (status, schedule, model, entry_point) → שינוי מחייב הרשאה + סיבה + Audit, לא תמיד ADR. מונע התנגשות עם CH4-012. |
| #3 (v0.2) | תדירות אפקטיבית | התדירות נשלטת גם על-ידי AGENT_INTERVAL_MINUTES וה-Workflow, לא רק schedule_cron. נעילה ובדיקה של התדירות האפקטיבית ונתיב ההפעלה. |
| #4 (v0.2) | כשל Identity ב-refreshPortfolioPrices | אי-התאמה אינה חוסמת Stop/מכירה/צמצום/הגנת P0. סיכון חדש נחסם, מופקת התרעה קריטית, יציאות והגנות ממשיכות לפעול. |
| #5 (v0.2) | SHA-256 על JSON קנוני | SHA-256 על JSON.stringify(sorted(...)). migration_ref מאומת מול רשימת משימות/ADR מאושרים — אינו טקסט חופשי. אין עדכון ישיר של identity_hash (רק דרך lockAgentIdentity). |
| #6 (v0.2) | AgentSnapshot Append-Only | תצלומים אינם ניתנים למחיקה/עדכון. נוספו: snapshot_batch_id, captured_at, captured_by, checksum. Rollback משחזר רק שדות מוגנים ואינו דורס last_run, מונים או נתוני פעילות מאוחרים. |
| #7 (v0.21) | config_hash חסר שדות תדירות | config_hash הורחב לכלול: status, schedule_cron, interval_minutes, market_hours_policy, model, entry_point. interval_minutes ו-market_hours_policy נגזרים מהקוד ונשמרים כ-effective_schedule_signature. |
| #8 (v0.21) | חסימת risk_breach Alert שגויה | ב-Fail-Safe, risk_breach Alert וכל התרעת סיכון ממשיכות להיווצר בעדיפות קריטית. נחסמות רק פעולות מגדילות סיכון (קנייה, פתיחת פוזיציה). |
| #9 (v0.21) | entry_point דורש migration_ref | שינוי entry_point מחייב migration_ref/ADR מאושר, לא config_change_ref בלבד — משום שהוא משנה את נתיב הביצוע. נוספו תנאי קבלה מפורשים + הוכחת Append-Only. |
CH4 Backlog v0.1 אושר, אך אין נקודת ייחוס מדויקת של זהויות הסוכנים. ללא נעילת זהויות, כל שינוי עתידי (Rename, מחיקה, הפעלה שקטה של Financial Reports, שינוי תזמון) עלול לחלוף בשתיקה ולשבור תלויות בכל המערכת — במיוחד את נתיבי ההפעלה runAgentScan ו-refreshPortfolioPrices.
לקבע נקודת ייחוס מדויקת של ששת הסוכנים (5 פעילים + Financial Reports מושהה), לנעול את זהויותיהם באמצעות Identity Hash (SHA-256), ולהוסיף בדיקת Invariant דו-שכבתית (זהות קבועה מול תצורה תפעולית) שמתריעה על כל שינוי שאינו מלווה בהרשאה מתאימה. כמו כן, לשמור Snapshot גרסאי Append-Only שניתן להשוות לפני ואחרי כל משימת CH4.
| agent_id | שם | סוג | אזור | שוק | סטטוס | תדירות | נקודת כניסה | מודל | החלטות |
|---|---|---|---|---|---|---|---|---|---|
| 6a676b17e7a59f5f82659b3c | US Scanner | scanner | US | NYSE | active | 15ד | runAgentScan | gemini_3_flash | 4,848 |
| 6a676b17e7a59f5f82659b3d | IL Scanner | scanner | IL | TASE | active | 15ד | runAgentScan | gemini_3_flash | 5,124 |
| 6a676b17e7a59f5f82659b3e | News Analyst | news | US | NASDAQ | active | 30ד | runAgentScan | gemini_3_flash | 4,960 |
| 6a676b17e7a59f5f82659b40 | Technical Analyst | technical | US | NASDAQ | active | 60ד | runAgentScan | gemini_3_flash | 4,814 |
| 6a68ab80bb6d9dcccd6961dd | Portfolio Risk Agent | portfolio | US | NYSE | active | 30ד | refreshPortfolioPrices | gemini_3_flash | 439 |
| 6a676b17e7a59f5f82659b3f | Financial Reports | financials | US | NYSE | paused | 720ד | runAgentScan (filtered) | gemini_3_flash | 12 |
תצפיות עיקריות:
סה"כ 6 רשומות: 5 פעילות (active) + 1 מושהית (paused = Financial Reports).
אין רשומת CIO ב-AgentConfig — runAgentScan עצמו מתפקד כ-CIO (CH3-001 §4.2: PURE CIO — ניתוח LLM + Risk Gate + Approval, ללא executeTrade).
Portfolio Risk Agent הוא היחיד שרץ דרך refreshPortfolioPrices (המבצע היחיד); runAgentScan מסנן אותו החוצה במפורש (name !== "Portfolio Risk Agent").
Financial Reports מסונן מ-runAgentScan כי status !== "active"; ה-Scheduler שלו (720 דקות) אינו פעיל כל עוד הרשומה מושהית.
אין סוכני IL News או IL Technical — רק IL Scanner מכסה את השוק הישראלי.
כל הסוכנים משתמשים במודל gemini_3_flash עם add_context_from_internet: true.
התדירות האפקטיבית נשלטת על-ידי שלושה גורמים: schedule_cron (Workflow), AGENT_INTERVAL_MINUTES (קוד runAgentScan), ו-MARKET_HOURS_TYPES — לא רק schedule_cron.
MARKET_HOURS_TYPES = {scanner, news, technical} — סוכנים אלו רצים רק כשהשוק פתוח; portfolio ו-financials רצים ללא תלות בשעות המסחר.
LLM Output Schema מאוחד: { summary, market_sentiment, symbols: [{ symbol, name, asset_type, recommendation, confidence, reasoning, current_price, target_price }] } — אך אינו גרסאי ואינו מתועדכן כ-Schema (זו בדיוק הבעיה ש-CH4-003 יפתור).
| נתיב | תיאור | סוכנים |
|---|---|---|
| runAgentScan | טוען agents מ-AgentConfig, מסנן status="active" ומסנן החוצה את Portfolio Risk Agent. מבצע CIO_SCAN (LLM) → RISK_GATE (דטרמיניסטי) → APPROVAL (יצירת Trade). אינו קורא ל-executeTrade. | US Scanner, IL Scanner, News Analyst, Technical Analyst |
| refreshPortfolioPrices | המבצע היחיד (CH3-001 §4.2). טוען את Portfolio Risk Agent לפי שם. צינור: PRICE_REFRESH → TRADE_VALIDITY → CIO_SCAN → EXECUTION. שלב EXECUTION דטרמיניסטי בלבד (אפס LLM). | Portfolio Risk Agent |
| CIO (מערכתי) | אין רשומת CIO ב-AgentConfig. runAgentScan עצמו מבצע את תפקיד ה-CIO: ניתוח LLM, Risk Gate דטרמיניסטי ויצירת Trade. CIO נפרד (CH4-008) ייווצר רק ב-Shadow ותלוי ב-CH3-005 (Decision Object). | — (מערכתי) |
4א · זהות קבועה — שינוי מחייב Migration/ADR
| שדה | סוג | תיאור |
|---|---|---|
| agent_id | string | מזהה ייחודי קבוע. שינוי/מחיקה+יצירה מחדש מפיק hash שונה — מונע החלפת זהות בשתיקה. |
| name | string | שם הסוכן הקנוני. שינוי שם שובר קישוריות ב-Audit, Messages, Alerts ו-AgentLog. |
| type | enum | סוג הסוכן (scanner/news/technical/financials/portfolio). שינוי סוג שובר את AGENT_INTERVAL_MINUTES ו-MARKET_HOURS_TYPES. |
| region | enum | אזור גיאוגרפי (US/IL/EU/ASIA). שינוי אזור משנה את הקונטקסט בפרומפט. |
| market | enum | בורסה (NYSE/NASDAQ/TASE/...). שינוי שוק משנה את סיומות הסמלים ואת isMarketOpen(). |
4ב · תצורה תפעולית — שינוי מחייב הרשאה + סיבה + Audit (לא תמיד ADR)
| שדה | סוג | תיאור |
|---|---|---|
| status | enum | סטטוס תפעולי (active/paused/inactive). שינוי מחייב הרשאה + סיבה + Audit (לא תמיד ADR). CH4-012 מאפשר Pause/Activate מבוקר דרך מסלול זה. |
| schedule_cron | string | תזמון Cron של ה-Workflow. שינוי מחייב הרשאה + סיבה + Audit. |
| model | string | מודל LLM. שינוי מחייב הרשאה + סיבה + Audit + בדיקת רגרסיה. |
| entry_point | string | נתיב הפעלה קנוני (runAgentScan / refreshPortfolioPrices). שינוי מחייב migration_ref/ADR מאושר — לא מספיק config_change_ref — משום שהוא משנה את נתיב הביצוע עצמו (Fix #9 v0.21). שאר שדות התצורה דורשות config_change_ref בלבד. |
ההפרדה מונעת התנגשות בין נעילת הזהות לבין CH4-012 (Pause/Activate מבוקר): שינוי סטטוס דורש config_change_ref, לא ADR.
identity_hash = SHA-256 על JSON קנוני וממוין: JSON.stringify(sorted({agent_id, name, type, region, market})). שדות הזהות הקבועה בלבד — לא תצורה תפעולית.
config_hash = SHA-256 על JSON קנוני וממוין של {status, schedule_cron, interval_minutes, market_hours_policy, model, entry_point} — התצורה התפעולית המלאה (Fix #7 v0.21).
identity_hash ו-config_hash מאוחסנים ב-AgentConfig כשדות נפרדים; מחושבים בעת נעילה ונבדקים בכל טעינה/עדכון.
אין לעדכן identity_hash / config_hash ישירות דרך AgentConfig.update() — הם מחושבים ומאוחסנים אך ורק על-ידי lockAgentIdentity() / lockAgentConfig().
identity_locked (boolean): כאשר true, שינוי שדה זהות קבועה חייב ללוות ב-migration_ref (הפניה ל-ADR/משימת CH4 מאושרת).
migration_ref אינו טקסט חופשי — הוא מאומת מול רשימת משימות CH4 מאושרות או מסמכי ADR רשומים. אי-התאמה → דחייה + Audit.
config_locked (boolean): כאשר true, שינוי שדה תצורה תפעולית חייב ללוות ב-config_change_ref (הרשאה + סיבה). אין חובת ADR — מאפשר Pause/Activate מבוקר (CH4-012).
entry_point הוא יוצא מן הכלל: שינוי entry_point מחייב migration_ref/ADR מאושר (לא מספיק config_change_ref), משום שהוא משנה את נתיב הביצוע עצמו (Fix #9 v0.21). שאר שדות התצורה (status, schedule_cron, model) דורשות config_change_ref בלבד.
interval_minutes ו-market_hours_policy אינם ב-AgentConfig (נגזרים מהקוד: AGENT_INTERVAL_MINUTES, MARKET_HOURS_TYPES) — לכן מחושבים בעת נעילה ונשמרים כ-effective_schedule_signature (string) ב-AgentConfig, הכלול ב-config_hash (Fix #7 v0.21).
assertAgentIdentity(agent, expectedHash, migrationRef?) — פונקציה משותפת שנקראת לפני כל AgentConfig.update(). אם hash הזהות השתנה ואין migration_ref תקף → זריקת שגיאה + אירוע Audit.
assertAgentConfig(agent, expectedConfigHash, configChangeRef?) — בודק שינוי תצורה תפעולית. דורש config_change_ref עם מבצע, סיבה וחותם זמן.
אירוע Audit בהפרה: Message עם type="risk_warning", source="Agent Identity Guard", severity="critical", כולל agent_id, שדה שהשתנה, ערך ישן/חדש, migration_ref/config_change_ref שסופק.
הבדיקה פועלת גם בעת טעינת סוכן לריצה (runAgentScan / refreshPortfolioPrices) — לא רק בעדכון.
שדות שאינם זהות ואינם תצורה (last_run, decisions_count, strategy, sources) מתעדכנים בחופשיות ללא חסימה.
כשל Identity בתוך refreshPortfolioPrices אינו חוסם Stop, מכירה, צמצום, הגנת P0 או יצירת התרעות סיכון (Fix #8 v0.21).
פעולות שנחסמות: קנייה, פתיחת פוזיציה או כל פעולה מגדילת סיכון.
פעולות שממשיכות: Stop, מכירה, צמצום והגנות P0.
risk_breach Alert וכל התרעת סיכון — ממשיכות להיווצר בעדיפות קריטית. אסור לחסום יצירת התרעות במקרה כשל (Fix #8 v0.21).
מופקת התרעה קריטית: Alert severity="critical" + Message type="risk_warning", source="Agent Identity Guard", כולל agent_id, hash צפוי/מצוי.
יציאות (approved sells, stop-loss, take-profit) והגנות (protection review deadline, auto-sell) ממשיכות לפעול ללא השפעה.
הגבלה זו חלה רק ב-refreshPortfolioPrices; ב-runAgentScan כשל Identity חוסם את הסריקה כולה (אין סיכון למסחר חדש, ואין הגנות שצריך לשמר).
המערכת מתעדת את הכשל וממשיכה לעבד יציאות דטרמיניסטיות — אין מצב שבו חסימת זהות מונעת מכירת חירום.
התדירות האפקטיבית נקבעת על-ידי שלושה גורמים: schedule_cron (Workflow), AGENT_INTERVAL_MINUTES (קוד runAgentScan), ו-MARKET_HOURS_TYPES.
schedule_cron קובע מתי ה-Workflow מפעיל את הפונקציה; AGENT_INTERVAL_MINUTES מסנן סוכנים שרצו לאחרונה; MARKET_HOURS_TYPES חוסם סוכנים שאינם פעילים מחוץ לשעות המסחר.
נעילת התדירות האפקטיבית כוללת: status, schedule_cron, interval_minutes, market_hours_policy, model, entry_point — כולם ב-config_hash (Fix #7 v0.21). interval_minutes ו-market_hours_policy נגזרים מהקוד ונשמרים כ-effective_schedule_signature.
שינוי אחד מהשלושה מחייב config_change_ref (הרשאה + סיבה + Audit), לא תמיד ADR.
בדיקת התדירות האפקטיבית מתבצעת בעת טעינת הסוכן (assertAgentConfig), לא רק בעדכון AgentConfig.
ישות חדשה: AgentSnapshot — Append-Only. תצלומים אינם ניתנים למחיקה או לעדכון; רק להוספה.
שדות: agent_id, agent_name, snapshot_version (number, עולה), identity_hash, config_hash, config_json (JSON מלא), snapshot_batch_id (מזהה קבוצת לכיבה), captured_at (date-time), captured_by (string), checksum (SHA-256 של config_json), ch4_task_ref, notes.
captureAgentSnapshot(b, ch4TaskRef, capturedBy) — לוכד את כל 6 הסוכנים ב-bulkCreate; מקצה snapshot_batch_id משותף ו-snapshot_version עולה לכל סוכן; מחשב checksum לכל רשומה.
compareAgentSnapshots(before, after) — מחזיר diff של שדות שהשתנו בין שני תצלומים (כולל השוואת checksum).
Rollback: משחזר רק שדות מוגנים (identity + config) מתצלום ישן ואינו דורס last_run, decisions_count, strategy, sources או נתוני פעילות מאוחרים.
לכל משימת CH4: תצלום "לפני" לפני תחילת המשימה, ותצלום "אחרי" לאחר סיום — להוכחת אפס שינוי התנהגות לא מכוון.
| ישות | שינוי | שדות |
|---|---|---|
| AgentConfig | הוספת שדות | identity_hash (string), config_hash (string), effective_schedule_signature (string), identity_locked (boolean, default false), config_locked (boolean, default false), identity_locked_at (date-time), migration_ref (string), config_change_ref (string) |
| AgentSnapshot | ישות חדשה (Append-Only) | agent_id, agent_name, snapshot_version (number), identity_hash, config_hash, config_json (string), snapshot_batch_id (string), captured_at (date-time), captured_by (string), checksum (string), ch4_task_ref, notes |
| קובץ | תיאור |
|---|---|
| base44/shared/agentIdentity.ts | computeIdentityHash(agent) [SHA-256 על זהות קבועה], computeConfigHash(agent) [SHA-256 על תצורה תפעולית מלאה: status, schedule_cron, interval_minutes, market_hours_policy, model, entry_point], computeEffectiveScheduleSignature(agent) [נגזר מ-AGENT_INTERVAL_MINUTES + MARKET_HOURS_TYPES], lockAgentIdentity(b, agentId), lockAgentConfig(b, agentId), assertAgentIdentity(agent, expectedHash, migrationRef?), assertAgentConfig(agent, expectedConfigHash, configChangeRef?), validateMigrationRef(ref), updateAgentWithIdentityCheck(b, agentId, updates, migrationRef?, configChangeRef?) |
| base44/shared/agentSnapshot.ts | captureAgentSnapshot(b, ch4TaskRef, capturedBy), compareAgentSnapshots(before, after), getLatestSnapshot(b, agentId), rollbackFromSnapshot(b, agentId, snapshotVersion) — משחזר רק שדות מוגנים |
| base44/functions/captureAgentBaseline/entry.ts | פונקציה חד-פענית: לוכדת Baseline (identity + config), נועלת זהויות (identity_locked=true, config_locked=true) ומחזירה דוח. מופעלת ידנית פעם אחת. |
דוח ה-Baseline מציג בדיוק 6 רשומות: 5 active + 1 paused.
agent_id מופיע בטבלת Baseline ונכלל ב-identity_hash (Fix #1).
תדירויות אפקטיביות: US Scanner=15ד, IL Scanner=15ד, News=30ד, Technical=60ד, Financial Reports=720ד (מושהה), Portfolio Risk=30ד.
כל הסוכנים משתמשים במודל gemini_3_flash עם add_context_from_internet=true.
Portfolio Risk Agent רץ דרך refreshPortfolioPrices, לא דרך runAgentScan (מסונן החוצה לפי שם).
Financial Reports paused ומסונן מ-runAgentScan (status !== active).
אין רשומת CIO ב-AgentConfig — runAgentScan מתפקד כ-CIO מערכתי.
identity_hash (SHA-256 על {agent_id, name, type, region, market}) מחושב ומאוחסן לכל 6 הסוכנים; identity_locked=true לאחר Baseline.
config_hash (SHA-256 על {status, schedule_cron, interval_minutes, market_hours_policy, model, entry_point}) מחושב ומאוחסן לכל 6 הסוכנים; effective_schedule_signature נגזר מהקוד ונשמר; config_locked=true לאחר Baseline (Fix #7 v0.21).
ניסיון שינוי שדה זהות קבועה (name/type/region/market) ללא migration_ref תקף → חסימה + אירוע Audit.
ניסיון שינוי שדה תצורה תפעולית (status/schedule_cron/model/entry_point) ללא config_change_ref → חסימה + אירוע Audit.
migration_ref עם ערך לא-תקין (לא ברשימת משימות/ADR מאושרים) → דחייה + Audit.
ניסיון עדכון ישיר של identity_hash / config_hash דרך AgentConfig.update() → חסימה.
Pause/Activate מבוקר (CH4-012) עובר דרך config_change_ref מבלי לדרוש ADR — אין התנגשות עם נעילת הזהות.
כשל Identity ב-refreshPortfolioPrices: קנייה/פתיחת פוזיציה/פעולה מגדילת סיכון — נחסמות; Stop/מכירה/צמצום/הגנת P0 — ממשיכות (Fix #4).
כשל Identity ב-refreshPortfolioPrices: risk_breach Alert וכל התרעת סיכון ממשיכות להיווצר בעדיפות קריטית — אסור לחסום יצירת התרעות (Fix #8 v0.21).
כשל Identity ב-refreshPortfolioPrices: מופקת התרעה קריטית (Alert + Message).
כשל Identity ב-runAgentScan: הסריקה כולה נחסמת (אין הגנות לשמר).
עדכון שדות שאינם זהות ואינם תצורה (last_run, decisions_count, strategy) עובר ללא חסימה.
תדירות אפקטיבית נבדקת בעת טעינת סוכן (schedule_cron + interval + entry_point), לא רק בעדכון (Fix #3).
AgentSnapshot נוצר עם snapshot_batch_id, captured_at, captured_by, checksum — Append-Only (Fix #6).
Rollback מתצלום משחזר רק שדות מוגנים ואינו דורס last_run, decisions_count או נתוני פעילות מאוחרים (Fix #6).
תצלום "לפני" ו"אחרי" זהים בשדות הזהות והתצורה — אפס שינוי התנהגות.
שינוי entry_point עם config_change_ref בלבד (ללא migration_ref) → נדחה (Fix #9 v0.21).
שינוי entry_point עם migration_ref מאושר → אפשרי ומתועד.
ניסיון Update/Delete של רשומת AgentSnapshot → נדחה, להוכחת Append-Only (Fix #9 v0.21).
config_hash כולל effective_schedule_signature עם interval_minutes ו-market_hours_policy הנגזרים מהקוד (Fix #7 v0.21).
base44/entities/AgentConfig.jsonc — הוספת identity_hash, config_hash, effective_schedule_signature, identity_locked, config_locked, identity_locked_at, migration_ref, config_change_ref.
base44/entities/AgentSnapshot.jsonc — ישות חדשה Append-Only עם snapshot_batch_id, captured_at, captured_by, checksum.
base44/shared/agentIdentity.ts (חדש) — SHA-256 על זהות ותצורה, נעילה דו-שכבתית, בדיקת Invariant, אימות migration_ref.
base44/shared/agentSnapshot.ts (חדש) — לכידת תצלום Append-Only, השוואה, Rollback מוגבל לשדות מוגנים.
base44/functions/captureAgentBaseline/entry.ts (חדש) — לכידת Baseline חד-פענית + נעילת זהות ותצורה.
base44/functions/runAgentScan/entry.ts — הוספת assertAgentIdentity + assertAgentConfig בטעינת סוכנים; כשל חוסם סריקה.
base44/functions/refreshPortfolioPrices/entry.ts — הוספת assertAgentIdentity + assertAgentConfig בטעינת Portfolio Risk Agent; כשל ב-Fail-Safe (חוסם סיכון חדש, אינו חוסם הגנות).
src/pages/Ch4Spec001.jsx — עמוד מפרט זה (תיעוד).
1. יצירת AgentSnapshot entity (Append-Only, עם snapshot_batch_id, checksum).
2. הוספת שדות זהות ותצורה ל-AgentConfig entity (identity_hash, config_hash, effective_schedule_signature, identity_locked, config_locked, migration_ref, config_change_ref).
3. יצירת base44/shared/agentIdentity.ts: SHA-256 דו-שכבתי, נעילה, בדיקת Invariant, אימות migration_ref/config_change_ref.
4. יצירת base44/shared/agentSnapshot.ts: לכידה Append-Only, השוואה, Rollback מוגבל.
5. יצירת base44/functions/captureAgentBaseline/entry.ts: לכידה חד-פענית + נעילה.
6. הרצת captureAgentBaseline — לכידת Baseline ונעילה.
7. הוספת assertAgentIdentity + assertAgentConfig ל-runAgentScan (כשל חוסם סריקה).
8. הוספת assertAgentIdentity + assertAgentConfig ל-refreshPortfolioPrices (כשל ב-Fail-Safe: חוסם סיכון, אינו חוסם הגנות).
9. בדיקות קבלה: שינוי זהות ללא migration_ref → חסימה; שינוי תצורה ללא config_change_ref → חסימה; Pause/Activate דרך CH4-012 → עובד; כשל ב-refreshPortfolioPrices → הגנות ממשיכות.
10. תצלום "אחרי" והשוואה ל-Baseline — הוכחת אפס שינוי.
11. הפקת דוח ביצוע CH4-001.