Ana içeriğe atla
Özel ilkeler, herhangi bir ajan davranışı için kurallar yazmanızı sağlar: proje kurallarını uygulayın, sapmaları önleyin, yıkıcı işlemleri engelleyin, takılı kalan ajanları algılayın 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

// 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();
  },
});
Kurun:
failproofai policies --install --custom ./my-policies.js

Özel ilkeleri yüklemenin iki yolu

Seçenek 1: Kural tabanlı (önerilen)

*policies.{js,mjs,ts} dosyalarını .failproofai/policies/ dizinine koyun ve otomatik olarak yüklenir — herhangi bir bayrak veya yapılandırma değişikliğine gerek yoktur. Bu git hook’lar gibi çalışır: dosya koyun, işte olur.
# Proje seviyesi — git'e gönderilen, ekip ile paylaşılan
.failproofai/policies/security-policies.mjs
.failproofai/policies/workflow-policies.mjs

# Kullanıcı seviyesi — kişisel, tüm projeler için geçerli
~/.failproofai/policies/my-policies.mjs
Nasıl çalışır:
  • Hem proje hem de kullanıcı dizinleri taranır (birleşim — ilk-başarı-kazanır değil)
  • Dosyalar her dizin içinde alfabetik sırayla yüklenir. Sırayı kontrol etmek için 01-, 02- ön ekini 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)
  • Açık --custom ve yerleşik ilkelerle birlikte çalışır
Kural tabanlı ilkeler, kuruluşunuz için bir kalite standardı oluşturmanın en kolay yoludur. .failproofai/policies/ dizinini git’e gönderün ve her ekip üyesi otomatik olarak aynı kurallara sahip olur — geliştirici başına kurulum gerekmez. Ekibiniz yeni hata modlarını keşfettikçe, bir ilke ekleyin ve gönderin. Zamanla bunlar, her katkıyla iyileşmeye devam eden canlı bir kalite standardı haline gelir.

Seçenek 2: Açık dosya yolu

# Özel ilkeler dosyasıyla kurun
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ülmüş mutlak yol, customPoliciesPath olarak policies-config.json içinde depolanır. Dosya her hook olayında yeni yüklenir - olaylar arasında önbellekleme yoktur.

Her ikisini birlikte kullanma

Kural tabanlı ilkeler ve açık --custom dosyası birlikte bulunabilir. Yükleme sırası:
  1. Açık customPoliciesPath dosyası (yapılandırılmışsa)
  2. Proje kural tabanlı dosyaları ({cwd}/.failproofai/policies/, alfabetik)
  3. Kullanıcı kural tabanlı dosyaları (~/.failproofai/policies/, alfabetik)

API

İçeri Aktarma

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

Karar yardımcıları

İşlevEtkiKullanım zamanı
allow()İşleme sessizce izin verİşlem güvenli, mesaj gerekli değil
deny(message)İşlemi engelleAjan bu işlemi yapmamalı
instruct(message)Engellemeden bağlam ekleAjana takılı kalmamak için ekstra bağlam ver
deny(message) - mesaj Claude’a "Blocked by failproofai:" önekiyle gösterilir. Tek bir deny, tüm daha sonraki değerlendirmeleri kısa devre yapar. instruct(message) - mesaj, geçerli araç çağrısı için Claude’un bağlamına eklenir. Tüm instruct mesajları biriktirilir ve birlikte teslim edilir.
Kod değişikliği yapılmadan herhangi bir deny veya instruct mesajına policyParams içinde bir hint alanı ekleyerek ek rehberlik ekleyebilirsiniz — bu özel (custom/), proje kural tabanlı (.failproofai-project/), ve kullanıcı kural tabanlı (.failproofai-user/) ilkeler için de çalışır. Ayrıntılar için Yapılandırma → hint bölümüne bakın.

Bilgilendirici izin mesajları

allow(message) işleme izin verir ve Claude’a bir bilgilendirici mesaj geri gönderir. Mesaj, hook işleyicisinin stdout yanıtında additionalContext olarak teslim edilir — instruct ile aynı mekanizma kullanılır, ancak anlamsal olarak farklıdır: uyarı değil, bir durum güncellemesidir.
İşlevEtkiKullanım zamanı
allow(message)İzin ver ve Claude’a bağlam gönderKontrolün geçtiğini onaylayın veya kontrolün neden atlandığını açıklayın
Kullanım örnekleri:
  • Durum onayları: allow("All CI checks passed.") — Claude’a her şeyin yeşil olduğunu söyler
  • Açık başarısızlık açıklamaları: allow("GitHub CLI not installed, skipping CI check.") — Claude’a kontrolün neden atlandığını söyler böylece tam bağlama sahip olur
  • Birden fazla mesaj birikiyor: birkaç ilke her biri allow(message) döndürürse, tüm mesajlar yeni satırlarla birleştirilir ve birlikte teslim edilir
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.");

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

PolicyContext alanları

AlanTürAçıklama
eventTypestring"PreToolUse", "PostToolUse", "Notification", "Stop"
toolNamestring | undefinedÇağrılan araç (örneğin "Bash", "Write", "Read")
toolInputRecord<string, unknown> | undefinedAracın giriş parametreleri
payloadRecord<string, unknown>Claude Code’dan gelen tam ham olay yükü
sessionSessionMetadata | undefinedOturum bağlamı (aşağıya bakın)

SessionMetadata alanları

AlanTürAçıklama
sessionIdstringClaude Code oturum tanımlayıcısı
cwdstringClaude Code oturumunun çalışma dizini
transcriptPathstringOturumun JSONL transkript dosyasının yolu

Olay türleri

OlayNe zaman çalışırtoolInput içeriği
PreToolUseClaude bir araç çalıştırmadan önceAracın girişi (örneğin Bash için { command: "..." })
PostToolUseBir araç tamamlandıktan sonraAracın girişi + tool_result (çıkış)
NotificationClaude bir bildirim gönderdiğinde{ message: "...", notification_type: "idle" | "permission_prompt" | ... } - hook’lar her zaman allow() döndürmelidir, bildirim’leri engelleyemezler
StopClaude oturumu sona erdiğindeBoş

Değerlendirme sırası

İlkeler bu sırayla değerlendirilir:
  1. Yerleşik ilkeler (tanım sırasında)
  2. customPoliciesPath dan gelen açık özel ilkeler (.add() sırasında)
  3. Proje .failproofai/policies/ den gelen kural tabanlı ilkeler (dosyalar alfabetik, içinde .add() sırasında)
  4. Kullanıcı ~/.failproofai/policies/ den gelen kural tabanlı ilkeler (dosyalar alfabetik, içinde .add() sırasında)
İlk deny tüm sonraki ilkeleri kısa devre yapar. Tüm instruct mesajları biriktirilir ve birlikte teslim edilir.

Geçişli içeri aktarmalar

Özel ilke dosyaları bağıl yollar kullanarak yerel modülleri içeri aktarabilir:
// 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şılabilen tüm bağıl içeri aktarmalar çözülür. Bu, from "failproofai" içeri 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 çalışacağını sınırlamak için match.events kullanın:
customPolicies.add({
  name: "require-summary-on-stop",
  match: { events: ["Stop"] },
  fn: async (ctx) => {
    // Yalnızca oturum sona erdiğinde çalışır
    // ctx.session.transcriptPath tam oturum günlüğünü içerir
    return allow();
  },
});
Her olay türünde çalışması için match tamamen çıkarın.

Hata işleme ve başarısızlık modları

Özel ilkeler açık başarısızlık: hatalar asla yerleşik ilkeleri engellemeyen veya hook işleyiciyi kıramaz.
BaşarısızlıkDavranış
customPoliciesPath ayarlanmamışAçık özel ilkeler çalışmaz; kural tabanlı ilkeler ve yerleşik olanlar normal devam eder
Dosya bulunamadıUyarı ~/.failproofai/hook.log dosyasına kaydedilir; yerleşik olanlar devam eder
Söz dizimi/içeri aktarma hatası (açık)Hata ~/.failproofai/hook.log dosyasına kaydedilir; açık özel ilkeler atlanır
Söz dizimi/içeri aktarma hatası (kural tabanlı)Hata kaydedilir; bu dosya atlanır, diğer kural tabanlı dosyalar yüklenir
fn çalışma zamanında hata atarsaHata kaydedilir; bu hook allow olarak işlenir; diğer hook’lar devam eder
fn 10 saniyeden daha uzun sürerseZaman aşımı kaydedilir; allow olarak işlenir
Kural tabanlı dizin eksikseKural tabanlı ilkeler çalışmaz; hata yok
Özel ilke hatalarını hata ayıklamak için günlük dosyasını izleyin:
tail -f ~/.failproofai/hook.log

Tam örnek: birden fazla ilke

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

// Ajanın secrets/ dizinine yazmasını engelle
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();
  },
});

// Ajanı takılı tutun: göndermeden önce testleri doğrula
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 önle
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 hemen çalıştırılabilir ilke dosyaları içerir:
Dosyaİçerik
examples/policies-basic.jsYaygın ajan başarısızlık modlarını kapsayan beş başlangıç ilkesi
examples/policies-advanced/index.jsGelişmiş desenler: geçişli içeri aktarmalar, zaman uyumsuz çağrılar, çıkış temizleme, ve oturum sonu hook’ları
examples/convention-policies/security-policies.mjsKural tabanlı güvenlik ilkeleri (.env yazma bloğu, git geçmişi yeniden yazma engelle)
examples/convention-policies/workflow-policies.mjsKural tabanlı iş akışı ilkeleri (test hatırlatıcıları, denetim dosyası yazmaları)

Açık dosya örneklerini kullanma

failproofai policies --install --custom ./examples/policies-basic.js

Kural tabanlı örnekleri kullanma

# 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/
Kurulum komutu gerekmez — dosyalar sonraki hook olayında otomatik olarak alınır.