הג'וב `sync-case-status` נכשל בכל ריצה על `legalApiBaseUrl unresolved` →
`TypeError: fetch failed`, לפני שהגיע ל-`pickSyncTargetIssue` — ובכל זאת
`plugin_job_runs.status = succeeded`, כי ה-try/catch ב-worker.ts בלע את
הכישלון ל-logger.error. 3,082 מופעי `unresolved` ו-98,571 מופעי
`company context is required` בלוג; כתיבה אחרונה בפועל 2026-07-22.
סיבת-השורש: מאז @paperclipai/server 2026.722.0 אין scope של חברה ב-runJob
(plugin-job-scheduler.js:184 שולח בלי companyId), ולכן כל ctx.config.get /
ctx.issues.* נדחית ב-InvocationScopeDeniedError (-32005).
- `src/company-scope.ts` — הפשטה טהורה (כמו sync-target.ts, ניתנת לטסט בלי
runWorker): פתרון base-URL עם cache ב-ctx.state + memo ברמת-המודול כדי
לא לכתוב ל-Postgres בכל בקשה, וזיהוי **מבני** של דחיית-scope לפי
`err.code` ולא התאמת-מחרוזת על ההודעה.
- `runJobHandler` מלוגג **וזורק מחדש** — המתזמר רושם `status:"failed"`
במקום `succeeded`. ה-try/catch הבולע הוסר (כלל-הנדסה §6).
- כשה-scope אינו זמין: `CompanyScopeUnavailableError` מפורש במקום ניחוש.
Invariants: כלל-הנדסה §6 (אין בליעה שקטה — זה לב התיקון) · G2 (הפשטה אחת
לכל הג'ובים, לא טיפול פר-ג'וב) · G1 (נרמול במקור).
Closes#637