4 Commits

Author SHA1 Message Date
5a5fdd9162 Merge pull request 'ci(int9): חיווט שער-INV-INT9 ל-Gitea Actions — 🚧 חסום עד שיירשם runner (legal-ai #618)' (#15) from chore/618-int9-workflow-enable into main
All checks were successful
INV-INT9 issue.status write-ownership / int9-guard (push) Successful in 3s
2026-09-02 11:29:38 +00:00
76db4aadb5 ci(int9): חיווט שער-INV-INT9 ל-Gitea Actions (legal-ai #618) — חסום עד שיירשם runner
All checks were successful
INV-INT9 issue.status write-ownership / int9-guard (pull_request) Successful in 3s
הסקריפט `scripts/int9-guard.mjs` כבר ב-`main` (PR #14) ורץ ידנית דרך
`npm run int9:guard`. הקובץ כאן הוא החיווט שלו ל-CI.

**אל תמזג לפני שיירשם runner ל-plugin-legal-ai.** ה-runner היחיד על nautilus
רשום בהיקף-repo ל-`legal-ai` בלבד (`action_runner.repo_id = 6`), ולכן job של
הריפו הזה לא נאסף לעולם — נמדד: ריצה 3200 / job 3250 ב-`queued` עם
`started_at: 1970-01-01`, בזמן שה-runner היה `busy: false` והריץ 7/7 שערים
של legal-ai. מיזוג עכשיו היה מייצר check תקוע-לנצח על **כל** PR עתידי בריפו.

ה-PR הזה הוא גם המדידה: ביום שיירשם runner הוא יהפוך לירוק מעצמו.

Refs ezer-mishpati/legal-ai#618

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-02 04:41:53 +03:00
c6c0b76914 Merge pull request 'chore(int9): שער-סטטי ל-INV-INT9 — issues.update({status}) רק במסלול sync-case-status (legal-ai #618)' (#14) from chore/618-inv-int9-ci-gate into main 2026-09-02 01:41:23 +00:00
b24d816cc0 chore(int9): שער-סטטי ל-INV-INT9 — issues.update({status}) רק במסלול sync-case-status (legal-ai #618)
ל-`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.** ה-runner היחיד על nautilus רשום בהיקף-repo ל-`legal-ai`
בלבד (`action_runner.repo_id = 6`), ולכן job של הריפו הזה לא נאסף לעולם
(נמדד: ריצה 3200 / job 3250 תקוע ב-`queued`, `started_at: 1970-01-01`).
קובץ ה-workflow יושב ב-PR נפרד וחסום, כדי שלא ייכנס ל-`main` שער שמייצר
check תקוע-לנצח בכל PR עתידי. עד אז: `npm run int9:guard` /
`npm run int9:guard:self-test`.

מגבלה מוצהרת: תיל-מעידה סטטי, לא הוכחה — `issues.update(id, patch)` שבו
אובייקט-העדכון נבנה במקום אחר אינו נתפס.

Refs ezer-mishpati/legal-ai#618

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-02 04:40:19 +03:00
3 changed files with 23 additions and 1 deletions

View File

@@ -13,6 +13,14 @@ name: INV-INT9 issue.status write-ownership
# no reason is itself a violation — exceptions must be argued in writing).
#
# Pure Node, zero dependencies (scripts/int9-guard.mjs) — no `npm ci` needed.
#
# ⚠️ חסום למיזוג. אין היום runner ל-Gitea Actions בהיקף הריפו הזה: ה-runner
# היחיד על nautilus רשום בהיקף-repo ל-`legal-ai` בלבד (`action_runner.repo_id = 6`),
# ולכן job שנפתח כאן לא נאסף לעולם — נמדד ב-legal-ai #618: ריצה 3200 / job 3250
# ישבה ב-`queued` עם `started_at: 1970-01-01` בזמן שה-runner היה `busy: false`.
# ה-PR הזה נשאר פתוח **בכוונה** ומשמש כמדידה: ביום שיירשם runner לריפו הזה הוא
# יהפוך לירוק מעצמו, וזו תהיה הראיה ש-AC2 של #618 סופק. עד אז השער רץ ידנית:
# `npm run int9:guard` · `npm run int9:guard:self-test`.
on:
pull_request:

View File

@@ -14,7 +14,9 @@
"format": "biome format --write src/",
"format:check": "biome format src/",
"biome": "biome check src/",
"biome:fix": "biome check --write src/"
"biome:fix": "biome check --write src/",
"int9:guard": "node scripts/int9-guard.mjs",
"int9:guard:self-test": "node scripts/int9-guard.mjs --self-test"
},
"dependencies": {
"@paperclipai/plugin-sdk": "^2026.722.0",

View File

@@ -39,6 +39,18 @@
* node scripts/int9-guard.mjs <path>... # scan only the given files/directories
* node scripts/int9-guard.mjs --self-test # run the fixture suite (scripts/fixtures/int9/), prove the gate bites
*
* NOT WIRED INTO CI YET: the Gitea Actions runner on this server is
* registered at *repository* scope for `legal-ai` only
* (`action_runner.repo_id = 6`), so any job queued for `plugin-legal-ai` is
* never dispatched — measured on legal-ai issue #618, run 3200 / job 3250
* sat in `queued` with `started_at: 1970-01-01`. Until a runner is
* registered for this repo, run this by hand:
* npm run int9:guard
* npm run int9:guard:self-test
* The workflow file itself (`.gitea/workflows/int9-guard.yaml`) lives in a
* separate, deliberately-blocked PR, so merging it does not leave a
* permanently-pending check on every future PR in this repo.
*
* Zero dependencies (node:fs / node:path / node:process only) — no `npm ci`
* needed in CI; the runner image ships node 24.
*/