> ## Documentation Index
> Fetch the complete documentation index at: https://docs.befailproof.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Özel İlkeler

> JavaScript'te kendi ilkelerinizi yazın - kuralları uygulayın, kaymaları engelleyin, arızaları tespit edin, dış sistemlerle entegre olun

Özel ilkeler, herhangi bir aracı davranışı için kurallar yazmanızı sağlar: proje kurallarını uygulayın, kaymaları engelleyin, yıkıcı işlemleri kısıtlayın, takılı aracıları tespit edin veya Slack, onay iş akışları ve daha fazlasıyla entegre olun. Yerleşik ilkelerle aynı hook olay sistemini ve `allow`, `deny`, `instruct` kararlarını kullanırlar.

***

## Hızlı örnek

```js theme={null}
// my-policies.js
import { customPolicies, allow, deny, instruct } from "failproofai";

customPolicies.add({
  name: "no-production-writes",
  description: "Block writes to paths containing 'production'",
  match: { events: ["PreToolUse"] },
  fn: async (ctx) => {
    if (ctx.toolName !== "Write" && ctx.toolName !== "Edit") return allow();
    const path = ctx.toolInput?.file_path ?? "";
    if (path.includes("production")) {
      return deny("Writes to production paths are blocked");
    }
    return allow();
  },
});
```

Yükleyin:

```bash theme={null}
failproofai policies --install --custom ./my-policies.js
```

***

## Özel ilkeleri yüklemenin iki yolu

### Seçenek 1: Kurala Dayalı (önerilen)

`*policies.{js,mjs,ts}` dosyalarını `.failproofai/policies/` dizinine koyun ve bunlar otomatik olarak yüklenecektir — hiç bayrak veya yapılandırma değişikliği gerekmez. Bu, git hook'ları gibi çalışır: bir dosya koyun, işe başlar.

```
# Proje seviyesi — git'e kaydedilir, takım tarafından paylaşılır
.failproofai/policies/security-policies.mjs
.failproofai/policies/workflow-policies.mjs

# Kullanıcı seviyesi — kişisel, tüm projelere uygulanır
~/.failproofai/policies/my-policies.mjs
```

**Nasıl çalışır:**

* Hem proje hem de kullanıcı dizinleri taranır (birleşim — ilk kapsam kazanmaz)
* Dosyalar her dizin içinde alfabetik olarak yüklenir. Sırayı kontrol etmek için `01-`, `02-` ön eki kullanın
* Yalnızca `*policies.{js,mjs,ts}` ile eşleşen dosyalar yüklenir; diğer dosyalar yoksayılır
* Her dosya bağımsız olarak yüklenir (dosya başına açık başarısız olur)
* Açık `--custom` ve yerleşik ilkelerle birlikte çalışır

<Tip>
  Kurala dayalı ilkeler, kuruluşunuz için bir kalite standardı oluşturmanın en kolay yoludur. `.failproofai/policies/` öğesini git'e işleyin ve her takım üyesi aynı kuralları otomatik olarak alır — geliştirici başına kurulum gerekmez. Takımınız yeni arıza modlarını keşfettikçe, bir ilke ekleyin ve gönderin. Zamanla bunlar, her katkıyla gelişen ve iyileşen canlı bir kalite standardı haline gelir.
</Tip>

### Seçenek 2: Açık dosya yolu

```bash theme={null}
# Özel ilkeler dosyası ile yükleyin
failproofai policies --install --custom ./my-policies.js

# İlkeler dosyası yolunu değiştirin
failproofai policies --install --custom ./new-policies.js

# Yapılandırmadan özel ilkeler yolunu kaldırın
failproofai policies --uninstall --custom
```

Çözümlenen mutlak yol, `policies-config.json` içinde `customPoliciesPath` olarak depolanır. Dosya her hook olayında taze yüklenir - olaylar arasında önbelleğe alma yoktur.

### Her ikisini birlikte kullanma

Kurala dayalı ilkeler ve açık `--custom` dosyası bir arada bulunabilir. Yükleme sırası:

1. Açık `customPoliciesPath` dosyası (yapılandırılmışsa)
2. Proje kurala dayalı dosyalar (`{cwd}/.failproofai/policies/`, alfabetik)
3. Kullanıcı kurala dayalı dosyalar (`~/.failproofai/policies/`, alfabetik)

***

## API

### İçe Aktar

```js theme={null}
import { customPolicies, allow, deny, instruct } from "failproofai";
```

### `customPolicies.add(hook)`

Bir ilkeyi kaydeder. Aynı dosyada birden fazla ilke için gerektiği kadar çağırın.

```ts theme={null}
customPolicies.add({
  name: string;                         // gerekli - benzersiz tanımlayıcı
  description?: string;                 // `failproofai policies` çıkışında gösterilen
  match?: { events?: HookEventType[] }; // olay türüne göre filtreleyin; hepsini eşleştirmek için atlayın
  fn: (ctx: PolicyContext) => PolicyResult | Promise<PolicyResult>;
});
```

### Karar Yardımcıları

| İşlev               | Efekt                       | Kullanım zamanı                                   |
| ------------------- | --------------------------- | ------------------------------------------------- |
| `allow()`           | İşleme sessizce izin ver    | İşlem güvenlidir, mesaj gerekmez                  |
| `deny(message)`     | İşlemi engelle              | Aracı bu işlemi yapmamalıdır                      |
| `instruct(message)` | Engelle olmadan bağlam ekle | Aracıyı doğru yolda tutmak için ekstra bağlam ver |

`deny(message)` - mesaj Claude'a `"Blocked by failproofai:"` ön ekiyle görünür. Tek bir `deny` tüm diğer değerlendirmeleri kısaltır.

`instruct(message)` - mesaj Claude'un mevcut araç çağrısı için bağlamına eklenir. Tüm `instruct` mesajları birikimlenir ve birlikte teslim edilir.

<Tip>
  Herhangi bir `deny` veya `instruct` mesajına ekstra rehberlik ekleyebilirsiniz, `policyParams` içinde bir `hint` alanı ekleyerek — kod değişikliği gerekmez. Bu, özel (`custom/`), proje kurala dayalı (`.failproofai-project/`) ve kullanıcı kurala dayalı (`.failproofai-user/`) ilkelerle de çalışır. Ayrıntılar için [Yapılandırma → hint](/tr/configuration#hint-cross-cutting) bölümüne bakın.
</Tip>

### Bilgilendirici izin mesajları

`allow(message)` işleme izin verir **ve** Claude'a geri bilgilendirici bir mesaj gönderir. Mesaj, hook işleyicisinin stdout yanıtında `additionalContext` olarak teslim edilir — `instruct` tarafından kullanılan aynı mekanizma, ancak anlamsal olarak farklı: bir uyarı değil, bir durum güncellemesidir.

| İşlev            | Efekt                              | Kullanım zamanı                                                             |
| ---------------- | ---------------------------------- | --------------------------------------------------------------------------- |
| `allow(message)` | İzin ver ve Claude'a bağlam gönder | Bir kontrolün geçtiğini doğrula veya bir kontrolün neden atlandığını açıkla |

Kullanım durumları:

* **Durum onayları:** `allow("All CI checks passed.")` — Claude'a her şeyin yeşil olduğunu söyler
* **Açık başarısız açıklamalar:** `allow("GitHub CLI not installed, skipping CI check.")` — Claude'a bir kontrolün neden atlandığını söyler, böylece tam bağlamı vardır
* **Birden fazla mesaj birikmesi:** birkaç ilke her biri `allow(message)` döndürürse, tüm mesajlar satır sonlarıyla birleştirilir ve birlikte teslim edilir

```js theme={null}
customPolicies.add({
  name: "confirm-branch-status",
  match: { events: ["Stop"] },
  fn: async (ctx) => {
    const cwd = ctx.session?.cwd;
    if (!cwd) return allow("No working directory, skipping branch check.");

    // ... dal durumunu kontrol et ...
    if (allPushed) {
      return allow("Branch is up to date with remote.");
    }
    return deny("Unpushed changes detected.");
  },
});
```

### `PolicyContext` alanları

| Alan        | Tür                                    | Açıklama                                                    |
| ----------- | -------------------------------------- | ----------------------------------------------------------- |
| `eventType` | `string`                               | `"PreToolUse"`, `"PostToolUse"`, `"Notification"`, `"Stop"` |
| `toolName`  | `string \| undefined`                  | Çağrılan araç (ör. `"Bash"`, `"Write"`, `"Read"`)           |
| `toolInput` | `Record<string, unknown> \| undefined` | Aracın girdi parametreleri                                  |
| `payload`   | `Record<string, unknown>`              | Claude Code'dan tam ham olay yükü                           |
| `session`   | `SessionMetadata \| undefined`         | Oturum bağlamı (aşağıya bakın)                              |

### `SessionMetadata` alanları

| Alan             | Tür      | Açıklama                                  |
| ---------------- | -------- | ----------------------------------------- |
| `sessionId`      | `string` | Claude Code oturum tanımlayıcısı          |
| `cwd`            | `string` | Claude Code oturumunun çalışma dizini     |
| `transcriptPath` | `string` | Oturumun JSONL transkript dosyasının yolu |

### Olay türleri

| Olay           | Ne zaman başlatılır                 | `toolInput` içerikleri                                                                                                                                   |
| -------------- | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PreToolUse`   | Claude bir aracı çalıştırmadan önce | Aracın girdisi (ör. Bash için `{ command: "..." }`)                                                                                                      |
| `PostToolUse`  | Bir araç tamamlandıktan sonra       | Aracın girdisi + `tool_result` (çıktı)                                                                                                                   |
| `Notification` | Claude bir bildirim gönderdiğinde   | `{ message: "...", notification_type: "idle" \| "permission_prompt" \| ... }` - hook'lar her zaman `allow()` döndürmelidir, bildirimleri engelleyemezler |
| `Stop`         | Claude oturumu sona erdiğinde       | Boş                                                                                                                                                      |

***

## Değerlendirme sırası

İlkeler şu sırayla değerlendirilir:

1. Yerleşik ilkeler (tanım sırasında)
2. `customPoliciesPath` öğesinden açık özel ilkeler (`.add()` sırasında)
3. Proje `.failproofai/policies/` öğesinden kurala dayalı ilkeler (dosyalar alfabetik, içinde `.add()` sırası)
4. Kullanıcı `~/.failproofai/policies/` öğesinden kurala dayalı ilkeler (dosyalar alfabetik, içinde `.add()` sırası)

<Note>
  İlk `deny` tüm sonraki ilkeleri kısaltır. Tüm `instruct` mesajları birikimlenir ve birlikte teslim edilir.
</Note>

***

## Geçişken içe aktarmalar

Özel ilke dosyaları göreceli yollar kullanarak yerel modülleri içe aktarabilir:

```js theme={null}
// my-policies.js
import { isBlockedPath } from "./utils.js";
import { checkApproval } from "./approval-client.js";

customPolicies.add({
  name: "approval-gate",
  fn: async (ctx) => {
    if (ctx.toolName !== "Bash") return allow();
    const approved = await checkApproval(ctx.toolInput?.command, ctx.session?.sessionId);
    return approved ? allow() : deny("Approval required for this command");
  },
});
```

Giriş dosyasından ulaşılabilir tüm göreceli içe aktarmalar çözümlenir. Bu, `from "failproofai"` içe aktarmalarını gerçek dist yoluna yeniden yazarak ve ESM uyumluluğunu sağlamak için geçici `.mjs` dosyaları oluşturarak uygulanır.

***

## Olay türü filtrelemesi

Bir ilkenin ne zaman başlatılacağını sınırlamak için `match.events` kullanın:

```js theme={null}
customPolicies.add({
  name: "require-summary-on-stop",
  match: { events: ["Stop"] },
  fn: async (ctx) => {
    // Sadece oturum sona erdiğinde başlatılır
    // ctx.session.transcriptPath tam oturum günlüğünü içerir
    return allow();
  },
});
```

`match` öğesini tamamen atlayarak her olay türünde başlatılmasını sağlayın.

***

## Hata yönetimi ve arıza modları

Özel ilkeler **açık başarısız olur**: hatalar hiçbir zaman yerleşik ilkeleri engelleme veya hook işleyiciyi çökmez.

| Arıza                                           | Davranış                                                                                   |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `customPoliciesPath` ayarlanmadı                | Açık özel ilkeler çalışmaz; kurala dayalı ilkeler ve yerleşikler normal şekilde devam eder |
| Dosya bulunamadı                                | Uyarı `~/.failproofai/hook.log` öğesine kaydedilir; yerleşikler devam eder                 |
| Söz dizimine/içe aktarmaya hata (açık)          | Hata `~/.failproofai/hook.log` öğesine kaydedilir; açık özel ilkeler atlanır               |
| Söz dizimine/içe aktarmaya hata (kurala dayalı) | Hata kaydedilir; o dosya atlanır, diğer kurala dayalı dosyalar yine de yüklenir            |
| `fn` çalışma zamanında hatası oluşturur         | Hata kaydedilir; bu hook `allow` olarak değerlendirilir; diğer hook'lar devam eder         |
| `fn` 10 saniyeden fazla sürer                   | Zaman aşımı kaydedilir; `allow` olarak değerlendirilir                                     |
| Kurala dayalı dizin eksik                       | Kurala dayalı ilkeler çalışmaz; hata yok                                                   |

<Tip>
  Özel ilke hatalarını hata ayıklamak için günlük dosyasını izleyin:

  ```bash theme={null}
  tail -f ~/.failproofai/hook.log
  ```
</Tip>

***

## Tam örnek: birden fazla ilke

```js theme={null}
// my-policies.js
import { customPolicies, allow, deny, instruct } from "failproofai";

// Aracının secrets/ dizinine yazmasını engelleyin
customPolicies.add({
  name: "block-secrets-dir",
  description: "Prevent agent from writing to secrets/ directory",
  match: { events: ["PreToolUse"] },
  fn: async (ctx) => {
    if (!["Write", "Edit"].includes(ctx.toolName ?? "")) return allow();
    const path = ctx.toolInput?.file_path ?? "";
    if (path.includes("secrets/")) return deny("Writing to secrets/ is not permitted");
    return allow();
  },
});

// Aracıyı doğru yolda tutun: taahhüt etmeden önce testleri doğrulayın
customPolicies.add({
  name: "remind-test-before-commit",
  description: "Keep the agent on track: verify tests pass before committing",
  match: { events: ["PreToolUse"] },
  fn: async (ctx) => {
    if (ctx.toolName !== "Bash") return allow();
    const cmd = ctx.toolInput?.command ?? "";
    if (/git\s+commit/.test(cmd)) {
      return instruct("Verify all tests pass before committing. Run `bun test` if you haven't already.");
    }
    return allow();
  },
});

// Dondurma döneminde planlanmamış bağımlılık değişikliklerini engelleyin
customPolicies.add({
  name: "dependency-freeze",
  description: "Prevent unplanned dependency changes during freeze period",
  match: { events: ["PreToolUse"] },
  fn: async (ctx) => {
    if (ctx.toolName !== "Bash") return allow();
    const cmd = ctx.toolInput?.command ?? "";
    const isInstall = /^(npm install|yarn add|bun add|pnpm add)\s+\S/.test(cmd);
    if (isInstall && process.env.DEPENDENCY_FREEZE === "1") {
      return deny("Package installs are frozen. Unset DEPENDENCY_FREEZE to allow.");
    }
    return allow();
  },
});

export { customPolicies };
```

***

## Örnekler

`examples/` dizini çalışmaya hazır ilke dosyalarını içerir:

| Dosya                                                | İçerik                                                                                                    |
| ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `examples/policies-basic.js`                         | Yaygın aracı arıza modlarını kapsayan beş başlangıç ilkesi                                                |
| `examples/policies-advanced/index.js`                | Gelişmiş desenler: geçişken içe aktarmalar, eşzamansız çağrılar, çıktı temizleme ve oturum sonu hook'ları |
| `examples/convention-policies/security-policies.mjs` | Kurala dayalı güvenlik ilkeleri (.env yazışlarını engelle, git tarihini yeniden yazmayı önle)             |
| `examples/convention-policies/workflow-policies.mjs` | Kurala dayalı iş akışı ilkeleri (test hatırlatmaları, denetim dosyası yazışları)                          |

### Açık dosya örneklerini kullanma

```bash theme={null}
failproofai policies --install --custom ./examples/policies-basic.js
```

### Kurala dayalı örnekleri kullanma

```bash theme={null}
# Proje seviyesine kopyala
mkdir -p .failproofai/policies
cp examples/convention-policies/*.mjs .failproofai/policies/

# Veya kullanıcı seviyesine kopyala
mkdir -p ~/.failproofai/policies
cp examples/convention-policies/*.mjs ~/.failproofai/policies/
```

Yükleme komutu gerekmez — dosyalar bir sonraki hook olayında otomatik olarak alınır.
