chore(ci): שער-CI ל-INV-INT9 — issues.update({status}) רק במסלול sync-case-status (legal-ai #618)
All checks were successful
INV-INT9 issue.status write-ownership / int9-guard (pull_request) Successful in 10s
All checks were successful
INV-INT9 issue.status write-ownership / int9-guard (pull_request) Successful in 10s
ל-`issue.status` כותב לגיטימי אחד בפלאגין: הג'וב `sync-case-status`
(`ctx.jobs.register("sync-case-status", …)` ב-`src/worker.ts`). עד היום
האכיפה הייתה code-review בלבד — וזה בדיוק מה שאפשר את הבאג של legal-ai
#446 (flip-flop `done → in_progress`), כותב שני שנכנס בלי שאיש שם לב.
`scripts/int9-guard.mjs` — Node ESM חסר-תלויות. טוקנייזר תו-תו
(מחרוזות/תבניות עם `${}` מקונן/הערות/רגקס-ליטרלים) בונה מסכת "קוד רגיל",
ומעליה: כל `jobs.register("sync-case-status", …)` מגדיר **טווח-תווים מותר**
(איזון-סוגריים), וכל `issues.update(…)` שרשימת-הארגומנטים שלו מכילה את
המזהה `status` חייב לשבת בתוכו.
הגרעיניות היא טווח-קוד ולא רשימת-קבצים (הדפוס של `leak_guard.py` ב-legal-ai)
במכוון: הקריאה המותרת היחידה וכל קריאה עתידית אסורה יושבות באותו
`worker.ts`. הטווח נגזר מהמבנה האמיתי, ולכן שורד מעבר של הג'וב לקובץ אחר —
ושינוי שם-הג'וב מפיל את השער בקול במקום לפתוח חור שקט.
חריגה מכוונת: `// noqa: INT9 — <נימוק>`. `noqa: INT9` בלי נימוק הוא הפרה
בעצמו — אין השתקה שקטה. כשל-פענוח (סוגר שלא נסגר) מפיל את השער ולא נבלע.
`--self-test` מריץ 5 פיקסצ'רים (`scripts/fixtures/int9/`, מחוץ ל-`src/`
בכוונה) ומאמת ספירת-הפרות מדויקת — הוכחה בכל ריצת-CI שהשער נושך.
מגבלה מוצהרת: תיל-מעידה סטטי, לא הוכחה — `issues.update(id, patch)` שבו
אובייקט-העדכון נבנה במקום אחר אינו נתפס.
Refs ezer-mishpati/legal-ai#618
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
15
scripts/fixtures/int9/non-status-update.ts
Normal file
15
scripts/fixtures/int9/non-status-update.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
// פיקסצ'ר ל-scripts/int9-guard.mjs --self-test. לא קוד-ריצה.
|
||||
//
|
||||
// שתי קריאות ל-issues.update שאינן נוגעות ב-status כלל — לא הפרה.
|
||||
// השנייה בודקת שגבול-מילה אמיתי: "statusLabel" אינו תואם ל-/\bstatus\b/
|
||||
// (אין גבול-מילה בין ה-s של status ל-L של Label).
|
||||
|
||||
export async function renameOnly(ctx: any, target: any, statusLabel: string) {
|
||||
await ctx.issues.update(target.id, { title: "x" }, target.companyId);
|
||||
|
||||
await ctx.issues.update(
|
||||
target.id,
|
||||
{ description: statusLabel },
|
||||
target.companyId,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user