docs(dealix): governance pack, GTM/CX runbooks, guard scripts, Claude commands

Add Cursor skills and Dealix slash-command docs; hook guard scripts; ops checklists for staging gates A-D and PAID_BETA_READY verification; daily GTM and pilot/Proof Pack playbooks; cross-link command board, START_HERE, and execution pack. PR acceptance template includes local smoke and pytest results.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Sami Assiri 2026-05-02 15:59:49 +03:00
parent 6bc9b46652
commit f931dffa58
20 changed files with 1159 additions and 43 deletions

View File

@ -0,0 +1,11 @@
# أوامر Dealix (Claude Code)
ملفات Markdown في هذا المجلد تُحمَّل كـ **slash commands** عند ضبط Claude Code لمجلد الأوامر (انظر [وثائق Anthropic — Slash commands](https://docs.anthropic.com/en/docs/claude-code/slash-commands)).
| ملف | الغرض |
|-----|--------|
| `plan.md` | خطة تنفيذ فقط — اقرأ لوحة الأوامر أولاً |
| `review.md` | مراجعة قبل الدمج |
| `ship.md` | خطوات الإغلاق والتسليم |
المرجع التشغيلي: [`dealix/docs/ops/EXECUTION_GOVERNANCE_PACK.md`](../../dealix/docs/ops/EXECUTION_GOVERNANCE_PACK.md)

View File

@ -0,0 +1,16 @@
Read `dealix/docs/ops/DEALIX_ACTIVE_COMMAND_BOARD.md` first.
Create an execution plan only. Do not edit files.
Return:
1. Objective
2. Owner (Claude Work | Cursor | Human)
3. Files to touch
4. Files forbidden
5. Acceptance criteria
6. Verification commands
7. Risk level
8. Next action
If the task does not move Dealix toward PAID_BETA_READY, first payment/commitment, or first Proof Pack, reject it as distraction.

View File

@ -0,0 +1,16 @@
Review the current diff against Dealix execution rules in `dealix/docs/ops/DEALIX_ACTIVE_COMMAND_BOARD.md`.
Check:
- forbidden files touched?
- live send enabled?
- scraping added?
- pricing changed?
- safety rules changed?
- tests updated where needed?
- acceptance criteria met?
- docs/runbook updated if behavior changed?
Return:
- **PASS** or **BLOCKED** with reasons.

View File

@ -0,0 +1,13 @@
Prepare a merge readiness report only. Do not merge. Do not push.
Include:
- branch
- changed files
- summary
- tests run (paste key output lines)
- smoke status
- route status (`python dealix/scripts/print_routes.py` from `dealix/` if applicable)
- security/safety status
- whether safe to merge
- exact next human action

View File

@ -0,0 +1,122 @@
---
name: dealix-cursor-engineering
description: >-
Engineering execution for Dealix — tests, staging gates, smoke scripts, small
fixes. Use when changing dealix/api, scripts, or tests for launch readiness.
disable-model-invocation: true
---
# Dealix Cursor Engineering Skill
## Role
You are the engineering execution lead for Dealix. Your job is to make the current system pass gates and work reliably. Do not invent new product direction.
## Current Stage
Dealix is in Paid Beta execution mode.
The engineering goal is:
```text
Staging works
+ PAID_BETA_READY passes
+ no unsafe live action
+ tests pass
+ routes are clean
```
## Protected Branch
Do not work directly on `ai-company`. Use a small branch per task and open a PR.
## Hard Safety Rules
Never implement:
- LinkedIn scraping
- LinkedIn auto-DM
- cold WhatsApp
- Gmail live send
- Calendar live insert without approval
- Moyasar live charge
- secrets in code
- raw PII traces
- broad refactors
- hidden behavior changes
## Allowed Work
You may work on:
- staging fixes
- `dealix/scripts/launch_readiness_check.py`
- `dealix/scripts/smoke_staging.py`
- `dealix/scripts/smoke_inprocess.py`
- `dealix/scripts/print_routes.py`
- tests
- small endpoint bug fixes
- small frontend dashboard consuming existing endpoints
- route registration if endpoint already exists
## Forbidden Work
Do not change:
- pricing
- positioning claims
- safety policy
- live-send flags
- `.cursor/plans`
- public claims contradicting `POSITIONING_LOCK`
- service business model without approval
## Required Pre-Work Report
Before editing, output:
1. Problem
2. Files to edit
3. Why these files
4. Risk level
5. Verification commands
6. Rollback plan
## Required Commands
After changes, from `dealix/`:
```bash
APP_ENV=test pytest -q --no-cov
python scripts/print_routes.py
python scripts/smoke_inprocess.py
python scripts/launch_readiness_check.py
```
If staging URL exists:
```bash
python scripts/smoke_staging.py --base-url "$STAGING_BASE_URL"
python scripts/launch_readiness_check.py --base-url "$STAGING_BASE_URL"
```
## PR Rules
Open PR only if:
- tests pass
- route check passes
- smoke passes
- no live action was enabled
- changed files are minimal
- PR description includes verification output
## Final Report Required
End with:
- changed files
- commands run
- exact results
- remaining blockers
- whether it is safe to merge

View File

@ -0,0 +1,131 @@
---
name: dealix-execution-governor
description: >-
Enforces Dealix Paid Beta execution plan, Command Board alignment, and safety
gates for both strategy and engineering work. Use when planning or reviewing
any Dealix change.
disable-model-invocation: true
---
# Dealix Execution Governor
## Role
You are the execution governor for Dealix. Your job is not to invent random features. Your job is to enforce the current execution plan, keep all work aligned with the Paid Beta objective, and stop unsafe or distracting work.
## North Star
Dealix reaches real Paid Beta only when:
```text
PAID_BETA_READY
+ first payment or written commitment
+ first Proof Pack delivered
```
Canonical board: `dealix/docs/ops/DEALIX_ACTIVE_COMMAND_BOARD.md`
## Current Product Category
Dealix is a Saudi Revenue Execution OS / Autonomous Revenue Company OS.
It is not:
- CRM
- WhatsApp bot
- lead scraper
- generic AI assistant
- agency-only service
## Hard Rules
Never allow:
- LinkedIn scraping
- LinkedIn auto-DM
- cold WhatsApp
- Gmail live send
- Moyasar live charge
- secrets in chat or files
- raw PII in traces
- code changes without tests
- new product features before paid-customer pressure
- editing `.cursor/plans` (plan files)
- overpromising guaranteed results
## Required Execution Flow
For every task, first output:
1. Objective
2. Owner: Claude Work (docs/sales) or Cursor (code/tests)
3. Files to touch
4. Files not allowed to touch
5. Acceptance criteria
6. Verification commands
7. Rollback plan
Do not start implementation until this is written.
## Allowed Work by Owner
### Claude Work (strategy / sales / docs)
Allowed:
- `dealix/docs/`
- `dealix/docs/sales-kit/`
- sales scripts, battlecards, case studies, proof pack templates, onboarding playbooks, AEO/SEO content, positioning copy
Forbidden:
- `dealix/api/`
- `dealix/db/`
- `dealix/integrations/`
- migrations
- live-send settings
- branch protection or CI changes unless explicitly requested
### Cursor (engineering)
Allowed:
- tests
- API bug fixes
- staging fixes
- smoke scripts
- route checks
- small frontend dashboard (only if endpoint already exists)
- launch readiness fixes
Forbidden:
- changing pricing
- changing positioning
- changing safety rules
- enabling live send
- adding scraping
- large features
- touching `.cursor/plans`
## Definition of Done
A task is done only if:
- all changed files are listed
- tests or checks are run
- output includes pass/fail
- no forbidden files changed
- no live send enabled
- no secrets exposed
- the result moves Dealix closer to Paid Beta
## Required Final Report
Every response must end with:
- What changed?
- What did not change?
- What tests/checks passed?
- What is blocked?
- Next exact action

View File

@ -0,0 +1,105 @@
---
name: dealix-strategy-sales
description: >-
Strategy, GTM, sales, and documentation for Dealix only — no product code.
Use for sales kit, case studies, playbooks, and marketing docs under dealix/docs.
disable-model-invocation: true
---
# Dealix Strategy and Sales Skill
## Role
You are the Strategy, GTM, Sales, and Documentation lead for Dealix.
Your job is to create assets that help Dealix sell, deliver, prove value, and upgrade customers. You do not write product code.
## Primary Objective
Help Dealix reach:
```text
PAID_BETA_READY
+ first payment or written commitment
+ first Proof Pack delivered
```
## Allowed Files
You may work in:
- `dealix/docs/`
- `dealix/docs/sales-kit/`
- `dealix/docs/marketing/` (create if needed)
- `dealix/docs/customer-success/` (create if needed)
- landing copy only if explicitly requested
## Forbidden Files
Never edit:
- `dealix/api/`
- `dealix/db/`
- `dealix/integrations/`
- migrations
- `dealix/auto_client_acquisition/` core logic (non-doc)
- `.github/workflows/`
- `.cursor/plans`
- secrets
- live-send settings
## Current Assets
Use and extend existing assets:
- `dealix/docs/PAID_BETA_FULL_RUNBOOK_AR.md`
- `dealix/docs/PUBLIC_LAUNCH_READINESS.md`
- `dealix/docs/sales-kit/START_HERE.md`
- Layer 14 email sequences, battlecards, demo script under `dealix/docs/sales-kit/`
## Priority Queue
Work in this order unless the Command Board says otherwise:
1. Case Study Template
2. Proof Pack Template
3. AEO/SEO Content Plan
4. Agency Partner Pack
5. Customer Onboarding Scripts
6. Pitch Deck Outline only after 5 paid customers
## Output Standards
Every asset must include:
- purpose
- when to use
- target customer
- exact copy/scripts where applicable
- proof metrics
- forbidden claims
- upgrade path
## Forbidden Claims
Never say:
- guaranteed sales
- guaranteed leads
- scrape LinkedIn
- send to everyone
- fully automatic outreach
- no human approval needed
## Approved Positioning
Say: Dealix turns growth goals into opportunities, Arabic messages, approvals, follow-ups, and Proof Packs for Saudi companies and agencies — aligned with `dealix/docs/POSITIONING_LOCK.md`.
## Final Report Required
End with:
- Files created/updated
- How this helps outreach/demo/pilot/proof
- What still needs human execution
- Next recommended asset

View File

@ -1,5 +1,42 @@
## PR Title: [Agent/Feature/Fix] Brief Description ## PR Title: [Agent/Feature/Fix] Brief Description
### Dealix Paid Beta gate (required when this PR touches `dealix/`)
- **Objective:** what does this PR move forward?
- [ ] `PAID_BETA_READY` / staging readiness
- [ ] first payment or written commitment
- [ ] first Proof Pack
- [ ] pilot delivery
- [ ] customer proof / support
- [ ] other (explain — must align with [`dealix/docs/ops/DEALIX_ACTIVE_COMMAND_BOARD.md`](../dealix/docs/ops/DEALIX_ACTIVE_COMMAND_BOARD.md))
- **Owner:** [ ] Claude Work (docs/sales) [ ] Cursor (engineering) [ ] Human
- **Files changed:** (list)
- **Explicitly not changed (check all that apply):**
- [ ] no live send enabled
- [ ] no scraping / LinkedIn automation
- [ ] no cold WhatsApp
- [ ] no pricing change
- [ ] no safety rule change
- [ ] no `.cursor/plans` change
- **Tests / verification** (paste commands + key results):
```bash
cd dealix
APP_ENV=test pytest -q --no-cov
python scripts/print_routes.py
python scripts/smoke_inprocess.py
python scripts/launch_readiness_check.py
```
- **Risk:** [ ] low [ ] medium [ ] high
- **Merge decision:** [ ] safe to merge [ ] blocked
---
### 1. Business Context & Objective ### 1. Business Context & Objective
*لماذا نحتاج هذا التغيير؟ وكيف سيساهم في نمو الإيرادات أو الاستراتيجية (Sovereign OS)؟* *لماذا نحتاج هذا التغيير؟ وكيف سيساهم في نمو الإيرادات أو الاستراتيجية (Sovereign OS)؟*
- -

View File

@ -12,7 +12,7 @@ Layer 14 (بريد + battlecards + ديمو ١٢ دقيقة) → [`sales-kit/STA
**مراجع تقنية:** [`POST_MERGE_VERIFICATION.md`](POST_MERGE_VERIFICATION.md) · [`BRANCH_PROTECTION_AND_CI.md`](BRANCH_PROTECTION_AND_CI.md) · [`STAGING_DEPLOYMENT.md`](STAGING_DEPLOYMENT.md) · [`ops/RAILWAY_AI_COMPANY_BIND.md`](ops/RAILWAY_AI_COMPANY_BIND.md) **مراجع تقنية:** [`POST_MERGE_VERIFICATION.md`](POST_MERGE_VERIFICATION.md) · [`BRANCH_PROTECTION_AND_CI.md`](BRANCH_PROTECTION_AND_CI.md) · [`STAGING_DEPLOYMENT.md`](STAGING_DEPLOYMENT.md) · [`ops/RAILWAY_AI_COMPANY_BIND.md`](ops/RAILWAY_AI_COMPANY_BIND.md)
**تشغيل متعدد الوكلاء (Claude Work / Cursor):** [`ops/DEALIX_ACTIVE_COMMAND_BOARD.md`](ops/DEALIX_ACTIVE_COMMAND_BOARD.md) · [`ops/STAGING_PAID_BETA_READY_ONE_SHOT.md`](ops/STAGING_PAID_BETA_READY_ONE_SHOT.md) · [`ops/STAGING_WORKFLOW_GITHUB.md`](ops/STAGING_WORKFLOW_GITHUB.md) · [`ops/COMMERCIAL_CLOSE_COPY_CHECKLIST.md`](ops/COMMERCIAL_CLOSE_COPY_CHECKLIST.md) **تشغيل متعدد الوكلاء (Claude Work / Cursor):** [`ops/DEALIX_ACTIVE_COMMAND_BOARD.md`](ops/DEALIX_ACTIVE_COMMAND_BOARD.md) · [`ops/EXECUTION_GOVERNANCE_PACK.md`](ops/EXECUTION_GOVERNANCE_PACK.md) · [`ops/STAGING_PAID_BETA_READY_ONE_SHOT.md`](ops/STAGING_PAID_BETA_READY_ONE_SHOT.md) · [`ops/STAGING_WORKFLOW_GITHUB.md`](ops/STAGING_WORKFLOW_GITHUB.md) · [`ops/COMMERCIAL_CLOSE_COPY_CHECKLIST.md`](ops/COMMERCIAL_CLOSE_COPY_CHECKLIST.md)
--- ---

View File

@ -0,0 +1,72 @@
# Pilot ٧ أيام + Proof Pack — مسار عميل واحد
مرجع تنفيذي يكمّل [`../sales-kit/START_HERE.md`](../sales-kit/START_HERE.md) و[`../PAID_BETA_FULL_RUNBOOK_AR.md`](../PAID_BETA_FULL_RUNBOOK_AR.md) و[`../ops/COMMERCIAL_CLOSE_COPY_CHECKLIST.md`](../ops/COMMERCIAL_CLOSE_COPY_CHECKLIST.md). الهدف: عميل يشعر أنه «اشترى نتيجة» وليس «اشترى وعداً».
---
## قبل الدفع (٥ دقائق)
- راجع النسخ في `COMMERCIAL_CLOSE_COPY_CHECKLIST.md`: المبلغ، المدة، مخرجات الـ Pilot، عدم الإرسال الحي الافتراضي.
- جهّز رابط فاتورة Moyasar (يدوي) حسب الـ Runbook.
---
## يوم ١–٢ — Onboarding
**Checklist (أرسل للعميل أو املأ معه):**
| البند | مثال / ملاحظة |
|--------|----------------|
| رابط الموقع أو الصفحة الرئيسية | |
| القطاع + المدينة | |
| العرض الرئيسي (جملة واحدة) | |
| وصف العميل المثالي (ICP) | |
| القنوات المتاحة (إيميل، CRM، نماذج) — بدون واتساب بارد | |
| موافقة على سياسة الموافقات (لا إرسال حي بدون opt-in) | |
**لمسة بشرية:** مكالمة أو رسالة قصيرة (١٥ دقيقة max) لتأكيد الجدول والتوقعات.
---
## يوم ٣–٥ — التشغيل + لمسات
- شغّل أول مهمة متفق عليها (تشخيص / فرص / قائمة) حسب الكتالوج.
- **لمسة كل ٢٤–٤٨ ساعة:** تحديث حالة (حتى سطرين) — يمنع شعور «سكت البائع».
- سجّل في Operating Board: `reply_status`, `blockers`, `next_action`.
---
## يوم ٦ — مراجعة ١٥ دقيقة
**Agenda:**
1. ماذا اكتشفنا؟ (٣ نقاط)
2. ماذا أرسلنا للمراجعة؟ (أرقام أو أمثلة)
3. ماذا نحتاج من العميل قبل الأسبوع القادم؟
**جمع أدلة للـ Proof Pack:** لقطات شاشة (بموافقة)، أرقام قبل/بعد إن وُجدت، اقتباس موافق عليه للنشر لاحقاً.
---
## يوم ٧ — إغلاق Pilot → Starter
- عرض **Starter ٩٩٩/شهر** (أو ما هو مفعّل في التسعير) مع رابط دفع جديد.
- إن لم يوافق: حدد تاريخ متابعة واحد + سبب مختصر في السجل.
---
## قالب Proof Pack (نسخ ولصق)
**عنوان:** Proof Pack — [اسم الشركة] — [نطاق التاريخ]
1. **ملخص تنفيذي (٥٧ أسطر):** ماذا فعلنا خلال الأسبوع.
2. **مخرجات ملموسة:** عدد الفرص / المسودات / الجلسات (حسب ما اتُفق عليه).
3. **مخاطر القنوات:** ما الذي يجب مراقبته (امتثال، جودة، توقيت).
4. **خطة متابعة ٧ أيام:** ٣ خطوات للعميل + ٣ خطوات لك.
5. **التوصية:** استمرار Starter / تعديل النطاق / إيقاف مؤقت — مع سبب واحد واضح.
---
## حدود المنتج (تذكير)
لا توسّع Founder Console أو tenant model كامل قبل طلب عميل صريح — انظر [`../ops/DEALIX_ACTIVE_COMMAND_BOARD.md`](../ops/DEALIX_ACTIVE_COMMAND_BOARD.md) قسم Do Not Build.

View File

@ -0,0 +1,54 @@
# Claude Code — Hooks لـ Dealix (إعداد اختياري)
السكربتات تقرأ **JSON من stdin** (حدث `PreToolUse` من Claude Code). إذا لم يكن الشكل متوقعاً، تخرج `0` ولا تمنع (fail-open) لتجنب كسر الجلسة.
## السكربتات
- `dealix/scripts/guard_dealix_changes.py` — لأدوات تعديل ملفات (`Edit`, `Write`, `MultiEdit`, …)
- `dealix/scripts/guard_dealix_bash.py` — لأمر `Bash`
شغّلها من **جذر الريبو** (كما في الأمثلة أدناه). على Windows إذا لم يكن الأمر `python` في الـ PATH، استبدله بـ `py -3` في إعدادات الـ hooks وفي اختبار stdin أدناه.
## مثال `hooks` في `.claude/settings.json`
انسخ إلى إعدادات المشروع وادمج مع المفاتيح الموجودة (لا تحذف `projectInstructions` إلخ):
```json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write|MultiEdit",
"hooks": [
{
"type": "command",
"command": "python dealix/scripts/guard_dealix_changes.py"
}
]
},
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python dealix/scripts/guard_dealix_bash.py"
}
]
}
]
}
}
```
> تحقق من صيغة المخطط لدى نسخة Claude Code لديك؛ قد يختلف اسم المفتاح أو شكل الـ matcher.
## خروج الحظر
- عند منع العملية: سكربتاتنا تطبع سبباً على **stderr** وتخرج برمز **2** (أو غير صفر حسب ما يتوقعه عميل الـ hooks).
## اختبار يدوي
```bash
echo "{\"hook_event_name\":\"PreToolUse\",\"tool_name\":\"Edit\",\"tool_input\":{\"file_path\":\"dealix/api/main.py\"}}" | python dealix/scripts/guard_dealix_changes.py
echo "{\"hook_event_name\":\"PreToolUse\",\"tool_name\":\"Bash\",\"tool_input\":{\"command\":\"git push --force\"}}" | python dealix/scripts/guard_dealix_bash.py
```

View File

@ -1,82 +1,197 @@
# DEALIX_ACTIVE_COMMAND_BOARD # DEALIX_ACTIVE_COMMAND_BOARD
صفحة قيادة واحدة — حدّث التاريخ عند تغيير التركيز. الهدف منع تضارب Claude Work و Cursor على نفس الملفات. صفحة قيادة واحدة — «الدستور» التشغيلي. حدّث التاريخ والحقول عند تغيير التركيز. أي عمل لا يمر بالسلسلة أدناه يُعتبر **غير معتمد**.
---
## سلسلة الإلزام (بدونها = غير معتمد)
```text
Command Board (هذا الملف)
→ Assigned Owner (Claude Work | Cursor | Human)
→ Allowed Files
→ Acceptance Criteria
→ PR
→ Tests / CI
→ Human Review
→ Merge
→ Runbook Update (إن لزم)
```
--- ---
## North Star ## North Star
Dealix becomes Paid Beta **real** only when:
```text ```text
إغلاق Paid Beta حقيقية = PAID_BETA_READY (staging) + أول payment/commitment + أول Proof Pack PAID_BETA_READY (staging readiness gate)
+ first payment or written commitment
+ first Proof Pack delivered
``` ```
المرجع التنفيذي: [`../PAID_BETA_FULL_RUNBOOK_AR.md`](../PAID_BETA_FULL_RUNBOOK_AR.md) المرجع التنفيذي من الألف للياء: [`../PAID_BETA_FULL_RUNBOOK_AR.md`](../PAID_BETA_FULL_RUNBOOK_AR.md)
--- ---
## الفرع المحمي للنشر ## Current Stage
```text | Field | Value |
ai-company |--------|--------|
``` | Stage | Paid Beta execution |
| Protected deploy branch | `ai-company` |
| Active work | فرع صغير لكل مهمة → PR إلى `ai-company` |
| Dealix API CI (مطلوب للحماية عند تفعيلها) | Jobs: **`pytest`**, **`smoke_inprocess`**, **`launch_readiness`** (انظر `.github/workflows/dealix-api-ci.yml`) |
لا commits مباشرة — PR فقط، CI أخضر. لا commits مباشرة على `ai-company` — PR فقط، CI أخضر.
--- ---
## PR / فرع العمل النشط (عدّل عند الفتح) ## Do Not Build
- marketplace
- white-label
- LinkedIn scraping
- LinkedIn auto-DM
- cold WhatsApp
- live Gmail send
- live Moyasar charge (استخدم invoice يدوي حسب الـ Runbook)
- enterprise custom features
- أي كود منتج بدون ضغط عميل مدفوع واضح
- Saudi Revenue Graph / patch كبير قبل `PAID_BETA_READY`
- Founder Console واسع قبل أول عميل
- Tenant model + ledger كامل + background jobs (ما لم يُسجّل طلب عميل مرتين أو ألم تشغيلي)
---
## Current Allowed Work
### Claude Work (استراتيجية + مبيعات + توثيق — لا كود منتج)
**Allowed:**
- `dealix/docs/`, sales kit, case study templates
- AEO/SEO plans (docs)
- battlecards, demo scripts, proof pack templates
- customer success playbooks, positioning (ضمن `POSITIONING_LOCK`)
**Forbidden:**
- `dealix/api/`, `dealix/db/`, `dealix/integrations/`, migrations
- workflow files (`.github/workflows/`) ما لم يُطلب صراحة
- تغيير pricing بدون موافقة
- تغيير safety policy بدون موافقة
- لمس `.cursor/plans`
Skill: [`.cursor/skills/dealix-strategy-sales/SKILL.md`](../../../.cursor/skills/dealix-strategy-sales/SKILL.md)
### Cursor (هندسة — أصغر PR ممكن)
**Allowed:**
- staging fixes
- tests
- smoke scripts (`smoke_staging`, `smoke_inprocess`, `launch_readiness_check`)
- API bug fixes
- frontend dashboard صغير **فقط** إن كان الـ endpoint موجوداً مسبقاً
**Forbidden:**
- ميزات كبيرة جديدة
- live sends / scraping / cold WhatsApp
- تغيير pricing أو safety rules
- لمس `.cursor/plans`
Skill: [`.cursor/skills/dealix-cursor-engineering/SKILL.md`](../../../.cursor/skills/dealix-cursor-engineering/SKILL.md)
### الطرفان — حاكم التنفيذ
Skill: [`.cursor/skills/dealix-execution-governor/SKILL.md`](../../../.cursor/skills/dealix-execution-governor/SKILL.md)
---
## Current Priorities (رُتّل حسب الأثر)
1. دمج/استقرار Layer 13 + 14 على `ai-company` (إن وُجد فرع متبقٍ)
2. Branch protection على `ai-company` + required checks: `pytest`, `smoke_inprocess`, `launch_readiness`
3. Railway staging active — Service Root = `dealix`, Start = `uvicorn api.main:app --host 0.0.0.0 --port $PORT`, Health = `/health`
4. Secret `STAGING_BASE_URL` + smoke من CI أو يدوياً (انظر [`STAGING_WORKFLOW_GITHUB.md`](STAGING_WORKFLOW_GITHUB.md))
5. `PAID_BETA_READY` على الـ URL الفعلي
6. Moyasar invoice (يدوي حسب الـ Runbook)
7. 25 outreach
8. أول pilot
9. أول Proof Pack
---
## Definition of Done لأي مهمة
- الملفات الملموسة مذكورة **قبل** العمل
- لا ملفات ممنوعة
- تشغيل tests أو أوامر التحقق المذكورة في المهمة
- المخرجات توضح ماذا تغيّر
- لا live send ولا scraping مضاف
- لا لصق أسرار في PR أو شات
- PR صغير وقابل للمراجعة
- تحديث Runbook إذا غيّر سلوك التشغيل
---
## تقرير مقبول من Claude / Cursor (أي تقرير بدون هذا = مرفوض)
```text ```text
(لا يوجد PR نشط مذكور هنا — املأ عند بدء موجة) Objective:
Files touched:
Acceptance criteria:
Commands run:
Results:
Risks:
Blocked items:
Next human action:
``` ```
--- ---
## مسموح الآن (Allowed Work) ## لوحة متابعة يومية (انسخها)
```text | المحور | السؤال | الحالة |
Staging + إصلاحات تمنع فشل PAID_BETA_READY فقط |--------|--------|--------|
Sales kit + docs + قوالب outreach (بدون تغيير claims) | GitHub | هل `ai-company` محمي والـ checks مطلوبة؟ | ⬜ |
smoke_staging / launch_readiness_check | PR | هل كل PR صغير ومحدد؟ | ⬜ |
اختبارات لأي إصلاح تقني ضروري | CI | هل `pytest` / `smoke_inprocess` / `launch_readiness` ناجحة؟ | ⬜ |
``` | Staging | هل Railway Active؟ | ⬜ |
| Readiness | هل `PAID_BETA_READY`؟ | ⬜ |
| Sales | هل 25 تواصل؟ | ⬜ |
| Demo | هل عندك ديمو جاهز؟ | ⬜ |
| Pilot | هل payment/commitment؟ | ⬜ |
| Proof | هل أول Proof Pack؟ | ⬜ |
--- ---
## ممنوع (Do Not Build) — حتى إشعار آخر ## قاعدة منع التشتت
```text ```text
Saudi Revenue Graph / patch كبير قبل PAID_BETA_READY أي شيء لا يخدم Paid Beta خلال 7 أيام = لا يُبنى الآن
Founder Console / frontend جديد واسع قبل أول عميل
Tenant model + ledger كامل + background jobs (ما لم يُسجّل طلب عميل مرتين أو ألم تشغيلي)
marketplace / white-label
LinkedIn scraping أو auto-DM
cold WhatsApp
live Gmail send
live Moyasar charge (استخدم invoice يدوي)
تغيير pricing أو POSITIONING_LOCK أو safety rules بدون موافقة صريحة
``` ```
--- ---
## تجميد البناء (Build freeze)
لا PR لميزات جديدة قبل:
```text
PAID_BETA_READY على URL staging
```
بعدها: فقط ما يخدم البيع أو يصلح بوابة الإطلاق — انظر شروط «متى تبني كود» في الـ Runbook.
---
## روابط سريعة ## روابط سريعة
| موضوع | ملف | | موضوع | ملف |
|--------|------| |--------|------|
| أوامر staging → PAID_BETA_READY | [`STAGING_PAID_BETA_READY_ONE_SHOT.md`](STAGING_PAID_BETA_READY_ONE_SHOT.md) | | أوامر staging → PAID_BETA_READY | [`STAGING_PAID_BETA_READY_ONE_SHOT.md`](STAGING_PAID_BETA_READY_ONE_SHOT.md) |
| Secret + workflow | [`STAGING_WORKFLOW_GITHUB.md`](STAGING_WORKFLOW_GITHUB.md) | | Secret + workflow | [`STAGING_WORKFLOW_GITHUB.md`](STAGING_WORKFLOW_GITHUB.md) |
| تشغيل Claude (وثائق فقط) | [`DEALIX_CLAUDE_WORK_CHARTER.md`](DEALIX_CLAUDE_WORK_CHARTER.md) | | Claude Work charter | [`DEALIX_CLAUDE_WORK_CHARTER.md`](DEALIX_CLAUDE_WORK_CHARTER.md) |
| تشغيل Cursor (كود) | [`DEALIX_CURSOR_ENGINEERING_CHARTER.md`](DEALIX_CURSOR_ENGINEERING_CHARTER.md) | | Cursor engineering charter | [`DEALIX_CURSOR_ENGINEERING_CHARTER.md`](DEALIX_CURSOR_ENGINEERING_CHARTER.md) |
| إغلاق تجاري (نسخ/قائمة) | [`COMMERCIAL_CLOSE_COPY_CHECKLIST.md`](COMMERCIAL_CLOSE_COPY_CHECKLIST.md) | | إغلاق تجاري (نسخ/قائمة) | [`COMMERCIAL_CLOSE_COPY_CHECKLIST.md`](COMMERCIAL_CLOSE_COPY_CHECKLIST.md) |
| Claude slash commands + hooks | [`EXECUTION_GOVERNANCE_PACK.md`](EXECUTION_GOVERNANCE_PACK.md) |
| GTM يومي (٢٥ لمسة) | [`../sales-kit/DAILY_GTM_CHECKLIST_AR.md`](../sales-kit/DAILY_GTM_CHECKLIST_AR.md) |
| Pilot + Proof Pack | [`../customer-success/PILOT_7_DAY_AND_PROOF_PACK_AR.md`](../customer-success/PILOT_7_DAY_AND_PROOF_PACK_AR.md) |
| بوابات Staging AD | [`STAGING_HUMAN_GATES_A_D_AR.md`](STAGING_HUMAN_GATES_A_D_AR.md) |
| تحقق PAID_BETA_READY | [`PAID_BETA_READY_VERIFICATION_AR.md`](PAID_BETA_READY_VERIFICATION_AR.md) |
| تقرير قبول PR (قالب) | [`PR_ACCEPTANCE_REPORT_DEALIX_GOVERNANCE_PACK.md`](PR_ACCEPTANCE_REPORT_DEALIX_GOVERNANCE_PACK.md) |
---
*آخر تحديث هيكلي: حزمة الحوكمة (Skills + Commands + PR gate + hooks doc).*

View File

@ -0,0 +1,61 @@
# Dealix — حزمة الحوكمة التنفيذية
ربط Skills و Claude Commands و PR template وسكربتات الحماية بلوحة القيادة.
## 1. لوحة القيادة
- [`DEALIX_ACTIVE_COMMAND_BOARD.md`](DEALIX_ACTIVE_COMMAND_BOARD.md)
## 2. Cursor Agent Skills (مشروع — داخل الريبو)
| Skill | المسار |
|--------|--------|
| Execution Governor (الطرفان) | `.cursor/skills/dealix-execution-governor/SKILL.md` |
| Claude Work — استراتيجية ومبيعات | `.cursor/skills/dealix-strategy-sales/SKILL.md` |
| Cursor — هندسة | `.cursor/skills/dealix-cursor-engineering/SKILL.md` |
## 3. Claude Code — Slash commands
من جذر الريبو:
- `.claude/commands/dealix/plan.md``/dealix-plan` (حسب إعداد Claude Code لمجلد الأوامر)
- `.claude/commands/dealix/review.md``/dealix-review`
- `.claude/commands/dealix/ship.md``/dealix-ship`
مرجع Anthropic: [Slash commands](https://docs.anthropic.com/en/docs/claude-code/slash-commands)
## 4. Hooks (اختياري — دمج يدوي)
- مثال إعداد + تعليمات: [`CLAUDE_CODE_HOOKS_SETUP.md`](CLAUDE_CODE_HOOKS_SETUP.md)
- سكربتات: `dealix/scripts/guard_dealix_changes.py`, `dealix/scripts/guard_dealix_bash.py`
مرجع Anthropic: [Hooks](https://docs.anthropic.com/en/docs/claude-code/hooks)
## 5. PR template
- جذر الريبو: `.github/PULL_REQUEST_TEMPLATE.md` — يتضمن قسم **Dealix Paid Beta** عند تغيير `dealix/`
## 6. أربع طبقات ضمان + ثلاث بوابات جودة
**ضمان التنفيذ:**
1. Skill يحدد السلوك
2. Command Board يحدد الأولوية
3. PR Template يفرض الدليل
4. Branch Protection يمنع الدمج بدون CI ناجح
**بوابات الجودة:**
1. `PAID_BETA_READY`
2. payment / commitment
3. Proof Pack مسلّم
## 7. مسارات يومية (GTM + Pilot + Staging)
| الملف | الغرض |
|--------|--------|
| [`../sales-kit/DAILY_GTM_CHECKLIST_AR.md`](../sales-kit/DAILY_GTM_CHECKLIST_AR.md) | ٢٥ لمسة + متابعات + مواد Layer ١٤ |
| [`../customer-success/PILOT_7_DAY_AND_PROOF_PACK_AR.md`](../customer-success/PILOT_7_DAY_AND_PROOF_PACK_AR.md) | أسبوع pilot + قالب Proof Pack |
| [`STAGING_HUMAN_GATES_A_D_AR.md`](STAGING_HUMAN_GATES_A_D_AR.md) | تشيك سريع لبوابات GitHub + Railway + smoke + CI |
| [`PAID_BETA_READY_VERIFICATION_AR.md`](PAID_BETA_READY_VERIFICATION_AR.md) | أوامر `GO_PRIVATE_BETA` مقابل `PAID_BETA_READY` |
| [`PR_ACCEPTANCE_REPORT_DEALIX_GOVERNANCE_PACK.md`](PR_ACCEPTANCE_REPORT_DEALIX_GOVERNANCE_PACK.md) | قالب تقرير قبول للـ PR |

View File

@ -0,0 +1,49 @@
# التحقق من PAID_BETA_READY (محلي + Staging)
السكربت [`../../scripts/launch_readiness_check.py`](../../scripts/launch_readiness_check.py) يطبع أحد الخيارات:
- **`GO_PRIVATE_BETA`:** فحوصات in-process ناجحة (بدون `--base-url` أو قبل الفحص البعيد).
- **`PAID_BETA_READY`:** نفس الفحوصات + نجاح جميع طلبات GET المطلوبة على `--base-url`.
- **`NO_GO`:** فشل بوابة — لا تبيع بجدية حتى العلاج.
---
## ١) محلي (بدون Staging)
من جذر حزمة `dealix`:
```powershell
py -3 scripts/launch_readiness_check.py
```
توقع: **`VERDICT: GO_PRIVATE_BETA`** و `exit 0` عندما يكون الكود والـ landing سليمين.
---
## ٢) ضد Staging الحقيقي
```powershell
$env:STAGING_BASE_URL="https://your-staging.railway.app"
py -3 scripts/launch_readiness_check.py --base-url $env:STAGING_BASE_URL
```
توقع: **`VERDICT: PAID_BETA_READY`** و `exit 0` قبل إرسال روابط دفع جادة للعملاء.
---
## ٣) ما تم التحقق منه في بيئة التطوير (مرجع للـ PR)
| الأمر | النتيجة المتوقعة |
|--------|-------------------|
| `py -3 scripts/smoke_inprocess.py` | نهاية المخرجات تحتوي `SMOKE_INPROCESS_OK` و exit 0 |
| `py -3 scripts/launch_readiness_check.py` (بدون base-url) | `VERDICT: GO_PRIVATE_BETA` و exit 0 |
| `py -3 -m pytest` | جميع الاختبارات المطلوبة خضراء (ما عدا skipped المعتاد) |
> تشغيل **PAID_BETA_READY** على URL فعلي يبقى خطوة بشرية بعد نشر Railway وضبط `STAGING_BASE_URL` في الأسرار وفي جهازك.
---
## روابط
- [`STAGING_HUMAN_GATES_A_D_AR.md`](STAGING_HUMAN_GATES_A_D_AR.md)
- [`../PAID_BETA_FULL_RUNBOOK_AR.md`](../PAID_BETA_FULL_RUNBOOK_AR.md)

View File

@ -0,0 +1,59 @@
# تقرير قبول — حزمة الحوكمة Dealix (لصقه في وصف PR)
استخدم هذا القالب عند فتح PR من فرع العمل إلى **`ai-company`**. لا تلصق أسراراً.
---
```text
Objective:
دمج حزمة الحوكمة التنفيذية (Skills + أوامر Claude + سكربتات hooks + توثيق ops) مع تحديثات Runbook ولوحة الأوامر وقالب PR ومسارات GTM/CX الموثقة.
Files touched:
- .github/PULL_REQUEST_TEMPLATE.md
- .claude/commands/dealix/*.md
- .cursor/skills/dealix-*/SKILL.md
- dealix/docs/PAID_BETA_FULL_RUNBOOK_AR.md
- dealix/docs/ops/DEALIX_ACTIVE_COMMAND_BOARD.md
- dealix/docs/ops/EXECUTION_GOVERNANCE_PACK.md
- dealix/docs/ops/CLAUDE_CODE_HOOKS_SETUP.md
- dealix/docs/ops/STAGING_HUMAN_GATES_A_D_AR.md
- dealix/docs/ops/PAID_BETA_READY_VERIFICATION_AR.md
- dealix/docs/ops/PR_ACCEPTANCE_REPORT_DEALIX_GOVERNANCE_PACK.md (هذا الملف)
- dealix/docs/sales-kit/START_HERE.md
- dealix/docs/sales-kit/DAILY_GTM_CHECKLIST_AR.md
- dealix/docs/customer-success/PILOT_7_DAY_AND_PROOF_PACK_AR.md
- dealix/scripts/guard_dealix_changes.py
- dealix/scripts/guard_dealix_bash.py
Acceptance criteria:
- لا تعديل على dealix/api أو db أو integrations ضمن هذا PR (نطاق docs + حوكمة + guards فقط ما لم يُذكر غير ذلك).
- الروابط الداخلية بين الملفات الجديدة والقديمة سليمة.
- تقرير التحقق المحلي: smoke_inprocess + launch_readiness (بدون base-url) + pytest كما في PAID_BETA_READY_VERIFICATION_AR.md
Commands run (من مجلد dealix):
- py -3 scripts/smoke_inprocess.py
- py -3 scripts/launch_readiness_check.py
- py -3 -m pytest -q
Results:
- `smoke_inprocess.py`: `SMOKE_INPROCESS_OK`، exit 0
- `launch_readiness_check.py` (بدون `--base-url`): `VERDICT: GO_PRIVATE_BETA`، exit 0
- `pytest`: 797 passed، 6 skipped (بيئة تطوير حديثة)
Risks:
- Hooks اختيارية — إعداد خاطئ في Claude Code قد يعطل الجلسة؛ راجع CLAUDE_CODE_HOOKS_SETUP.md
- PAID_BETA_READY على Staging يتطلب إكمال بوابات AD يدوياً في GitHub/Railway
Blocked items:
- (إن وُجدت) — مثلاً: STAGING_BASE_URL غير مضبوط بعد
Next human action:
- دمج PR بعد مراجعة + CI أخضر
- إكمال STAGING_HUMAN_GATES_A_D_AR.md ثم تشغيل launch_readiness_check مع --base-url
```
---
## رابط PR المقترح
Base: **`ai-company`** — Compare: فرع العمل الحالي (مثلاً `docs/post-merge-pr32-link` أو فرع جديد بعد إعادة التسمية حسب سياسة الفريق).

View File

@ -0,0 +1,50 @@
# بوابات AD — مرجع سريع للإنسان
التفاصيل الكاملة في [`../PAID_BETA_FULL_RUNBOOK_AR.md`](../PAID_BETA_FULL_RUNBOOK_AR.md). هذا الملف للتشيك السريع فقط.
---
## A — حماية GitHub
- [ ] قاعدة فرع على **`ai-company`** (أو الفرع المحمي المعتمد).
- [ ] يتطلب PR قبل الدمج.
- [ ] يتطلب checks خضراء كما تظهر في واجهة GitHub: عادة `pytest`، `smoke_inprocess`، `launch_readiness` من workflow Dealix API CI.
- [ ] منع force push وحذف الفرع المحمي.
مرجع: [`BRANCH_PROTECTION_AND_CI.md`](BRANCH_PROTECTION_AND_CI.md)
---
## B — Railway Staging
- [ ] مشروع Railway من GitHub → الفرع المعتمد للنشر.
- [ ] **Service Root:** `dealix`
- [ ] **Start Command:** `uvicorn api.main:app --host 0.0.0.0 --port $PORT`
- [ ] **Healthcheck:** `/health`
- [ ] متغيرات آمنة: `APP_ENV=staging`، `WHATSAPP_ALLOW_LIVE_SEND=false`، `MOYASAR_MODE=sandbox` (حسب سياسة شركتك).
مرجع: [`STAGING_DEPLOYMENT.md`](STAGING_DEPLOYMENT.md) · [`RAILWAY_AI_COMPANY_BIND.md`](RAILWAY_AI_COMPANY_BIND.md)
---
## C — تحقق من جهازك
من مجلد `dealix` (بعد ضبط `STAGING_BASE_URL` بدون `/` زائدة في النهاية):
```powershell
$env:STAGING_BASE_URL="https://YOUR-STAGING-HOST"
py -3 scripts/smoke_staging.py --base-url $env:STAGING_BASE_URL
py -3 scripts/launch_readiness_check.py --base-url $env:STAGING_BASE_URL
```
- [ ] `smoke_staging.py` → exit 0
- [ ] `launch_readiness_check.py`**VERDICT: PAID_BETA_READY** و exit 0
---
## D — GitHub Actions
- [ ] Secret في الريبو: **`STAGING_BASE_URL`**
- [ ] تشغيل workflow **Dealix staging smoke** يدوياً مرة على الأقل للتحقق.
مرجع: [`STAGING_WORKFLOW_GITHUB.md`](STAGING_WORKFLOW_GITHUB.md) · الملف: [`.github/workflows/dealix-staging-smoke.yml`](../../../.github/workflows/dealix-staging-smoke.yml)

View File

@ -0,0 +1,40 @@
# قائمة GTM اليومية — Dealix Paid Beta
انسخ الجدول كل صباح. المرجع: [`../PAID_BETA_FULL_RUNBOOK_AR.md`](../PAID_BETA_FULL_RUNBOOK_AR.md) (المرحلة F) و[`../ops/DEALIX_ACTIVE_COMMAND_BOARD.md`](../ops/DEALIX_ACTIVE_COMMAND_BOARD.md) (لوحة المتابعة).
---
## أرقام اليوم (حد أدنى)
| المقياس | الهدف | اليوم |
|---------|--------|--------|
| لمسات يدوية (تواصل جديد) | ٢٥ | ⬜ |
| متابعات (follow-up) | ٥ | ⬜ |
| منشور LinkedIn | ١ | ⬜ |
| منشور X (أو منصة ثانية) | ١ | ⬜ |
| محادثة شريك / مورّد معرفة | ١ | ⬜ |
| محاولة حجز ديمو | ١ | ⬜ |
**قواعد:** لا scraping، لا auto-DM، لا واتساب بارد جماعي — التزم بسياسة المنصات والـ Runbook.
---
## مواد جاهزة (افتح حسب الحاجة)
| الملف | الاستخدام |
|--------|-----------|
| [`START_HERE.md`](START_HERE.md) | خريطة ١٤ يوم + ٩٩٩ ريال |
| [`layer14_email_sequences_4x7_ar.md`](layer14_email_sequences_4x7_ar.md) | بريد ومتابعة |
| [`layer14_battlecards_6_ar.md`](layer14_battlecards_6_ar.md) | اعتراضات المنافسين |
| [`layer14_demo_12min_script_ar.md`](layer14_demo_12min_script_ar.md) | ديمو قصير |
| [`dealix_demo_script_30min.md`](dealix_demo_script_30min.md) | ديمو كامل |
| [`dealix_objection_handler.md`](dealix_objection_handler.md) | قبل الديمو |
| [`dealix_14day_tracker.html`](dealix_14day_tracker.html) | تتبع يومي |
---
## نهاية اليوم (٣ أسطر في المفكرة)
1. أفضل رد حصلت عليه:
2. أكبر عائق:
3. أولوية الغد:

View File

@ -34,10 +34,12 @@
| [`layer14_email_sequences_4x7_ar.md`](layer14_email_sequences_4x7_ar.md) | ٤ تسلسلات × ٧ رسائل = ٢٨ بريداً جاهزاً (وكالات / تدريب / SaaS / خدمات محلية) | | [`layer14_email_sequences_4x7_ar.md`](layer14_email_sequences_4x7_ar.md) | ٤ تسلسلات × ٧ رسائل = ٢٨ بريداً جاهزاً (وكالات / تدريب / SaaS / خدمات محلية) |
| [`layer14_battlecards_6_ar.md`](layer14_battlecards_6_ar.md) | مواجهة HubSpot / Salesforce / Apollo / Wati / Clay / «AI عام» | | [`layer14_battlecards_6_ar.md`](layer14_battlecards_6_ar.md) | مواجهة HubSpot / Salesforce / Apollo / Wati / Clay / «AI عام» |
| [`layer14_demo_12min_script_ar.md`](layer14_demo_12min_script_ar.md) | سكربت ١٢ دقيقة بوتيرة سعودية + اعتراضات | | [`layer14_demo_12min_script_ar.md`](layer14_demo_12min_script_ar.md) | سكربت ١٢ دقيقة بوتيرة سعودية + اعتراضات |
| [`DAILY_GTM_CHECKLIST_AR.md`](DAILY_GTM_CHECKLIST_AR.md) | يومياً — ٢٥ لمسة + متابعات + روابط Layer ١٤ |
| [`../customer-success/PILOT_7_DAY_AND_PROOF_PACK_AR.md`](../customer-success/PILOT_7_DAY_AND_PROOF_PACK_AR.md) | بعد أول دفع — أسبوع pilot + قالب Proof Pack |
يُكمّل الجدول أعلاه ولا يستبدل `dealix_demo_script_30min.md` إذا احتجت ديمو أطول. يُكمّل الجدول أعلاه ولا يستبدل `dealix_demo_script_30min.md` إذا احتجت ديمو أطول.
**تنسيق العمل (Claude / Cursor):** [`../ops/DEALIX_ACTIVE_COMMAND_BOARD.md`](../ops/DEALIX_ACTIVE_COMMAND_BOARD.md) **تنسيق العمل (Claude / Cursor):** [`../ops/DEALIX_ACTIVE_COMMAND_BOARD.md`](../ops/DEALIX_ACTIVE_COMMAND_BOARD.md) · [`../ops/EXECUTION_GOVERNANCE_PACK.md`](../ops/EXECUTION_GOVERNANCE_PACK.md) (Skills + أوامر + PR + hooks)
--- ---

View File

@ -0,0 +1,65 @@
#!/usr/bin/env python3
"""Claude Code PreToolUse guard for Bash. Reads JSON from stdin.
Exit 0: allow. Exit 2: block. Unknown payload: allow (fail-open).
Run from repository root: python dealix/scripts/guard_dealix_bash.py
"""
from __future__ import annotations
import json
import re
import sys
def _command(data: dict) -> str:
ti = data.get("tool_input")
if isinstance(ti, dict):
for k in ("command", "cmd", "bash_command"):
v = ti.get(k)
if isinstance(v, str):
return v
return ""
def main() -> int:
try:
raw = sys.stdin.read()
data = json.loads(raw) if raw.strip() else {}
except json.JSONDecodeError:
return 0
if not isinstance(data, dict):
return 0
if data.get("hook_event_name") and data.get("hook_event_name") != "PreToolUse":
return 0
if str(data.get("tool_name") or "") != "Bash":
return 0
cmd = _command(data).strip()
if not cmd:
return 0
low = cmd.lower()
if re.search(r"\bgit\s+push\b.*(-f|--force)\b", low):
print("dealix guard_dealix_bash: blocked: git push --force", file=sys.stderr)
return 2
if "whatsapp_allow_live_send=true" in low.replace(" ", ""):
print("dealix guard_dealix_bash: blocked: WHATSAPP_ALLOW_LIVE_SEND=true", file=sys.stderr)
return 2
if "rm" in low and "-rf" in low and "/" in cmd:
# coarse guard against destructive rm -rf /
if re.search(r"rm\s+(-[a-z]*f[a-z]*\s+|-\w*f\w*\s+).*/\s*$", low) or " rm -rf /" in low:
print("dealix guard_dealix_bash: blocked: destructive rm pattern", file=sys.stderr)
return 2
return 0
if __name__ == "__main__":
raise SystemExit(main())

View File

@ -0,0 +1,98 @@
#!/usr/bin/env python3
"""Claude Code PreToolUse guard for file-writing tools. Reads JSON from stdin.
Exit 0: allow. Exit 2: block (stderr message). Unknown payload: allow (fail-open).
Run from repository root: python dealix/scripts/guard_dealix_changes.py
"""
from __future__ import annotations
import json
import sys
def _norm_path(s: str) -> str:
s = (s or "").replace("\\", "/").strip()
if not s:
return ""
# Normalize to forward slashes for substring checks
return s.lower()
def _iter_paths(tool_input: object) -> list[str]:
out: list[str] = []
if not isinstance(tool_input, dict):
return out
for key in ("file_path", "path", "target_file", "file"):
v = tool_input.get(key)
if isinstance(v, str) and v.strip():
out.append(v.strip())
for key in ("file_paths", "paths", "files"):
v = tool_input.get(key)
if isinstance(v, list):
for item in v:
if isinstance(item, str) and item.strip():
out.append(item.strip())
elif isinstance(item, dict):
out.extend(_iter_paths(item))
# MultiEdit-style nested edits
edits = tool_input.get("edits")
if isinstance(edits, list):
for e in edits:
if isinstance(e, dict):
out.extend(_iter_paths(e))
return out
def _forbidden_path_reason(norm: str) -> str | None:
if ".cursor/plans" in norm or norm.endswith("/.cursor/plans") or "/.cursor/plans/" in norm:
return "blocked path: .cursor/plans"
if not (norm.endswith(".env.example") or norm.endswith(".env.sample")):
if norm.endswith(".env") or "/.env." in norm:
return "blocked path: sensitive env file (.env*)"
low = norm
if "linkedin" in low and ("scrap" in low or "scrape" in low):
return "blocked: LinkedIn scraping path/name signal"
return None
def main() -> int:
try:
raw = sys.stdin.read()
data = json.loads(raw) if raw.strip() else {}
except json.JSONDecodeError:
return 0
if not isinstance(data, dict):
return 0
if data.get("hook_event_name") and data.get("hook_event_name") != "PreToolUse":
return 0
tool = str(data.get("tool_name") or "")
if tool and tool not in {
"Edit",
"Write",
"MultiEdit",
"NotebookEdit",
"StrReplace",
}:
# Only guard known file mutation tools; allow others
if "edit" not in tool.lower() and "write" not in tool.lower():
return 0
paths = _iter_paths(data.get("tool_input"))
if not paths:
return 0
for p in paths:
n = _norm_path(p)
reason = _forbidden_path_reason(n)
if reason:
print(f"dealix guard_dealix_changes: {reason}: {p}", file=sys.stderr)
return 2
return 0
if __name__ == "__main__":
raise SystemExit(main())