Ana içeriğe atla
Özel politikalar, herhangi bir agent davranışı için kurallar yazmanıza izin verir: proje kurallarını uygulayın, sapmayı önleyin, yıkıcı işlemleri engelle, sıkışmış aracıları algılayın veya Slack, onay iş akışları ve daha fazlasıyla entegre olun. Yerleşik politikalarla aynı hook etkinliği 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();
  },
});
Yükleyin:
failproofai policies --install --custom ./my-policies.js

Özel politikaları yüklemenin iki yolu

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

.failproofai/policies/ dizinine *policies.{js,mjs,ts} dosyalarını bırakın ve otomatik olarak yüklenirler — hiçbir bayrak veya yapılandırma değişikliğine gerek yoktur. Bu git hook’ları gibi çalışır: bir dosya bırakın ve çalışır.
# Proje düzeyi — git'e kaydedilir, ekiple paylaşılır
.failproofai/policies/security-policies.mjs
.failproofai/policies/workflow-policies.mjs

# Kullanıcı düzeyi — 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-kazanır değil)
  • Dosyalar her dizin içinde alfabetik olarak yüklenir. Sırayı kontrol etmek için 01-, 02- ile önekleyin
  • 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-fail)
  • Açık --custom ve yerleşik politikalarla birlikte çalışır
Kural politikaları, politikaları bir ekip genelinde paylaşmanın en kolay yoludur. .failproofai/policies/ öğesini git’e işleyin ve her takım üyesi otomatik olarak bunları alır.

Seçenek 2: Açık dosya yolu

# Özel politika dosyasıyla yükleyin
failproofai policies --install --custom ./my-policies.js

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

# Yapılandırmadan özel politika yolunu kaldırın
failproofai policies --uninstall --custom
Çözümlenen mutlak yol, policies-config.json içinde customPoliciesPath olarak depolanır. Dosya her hook etkinliğinde yeniden yüklenir - olaylar arasında önbellekleme yoktur.

Her ikisini birlikte kullanma

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

API

İçe aktarma

import { customPolicies, allow, deny, instruct } from "failproofai";

customPolicies.add(hook)

Bir politikayı kaydeder. Aynı dosyada birden çok politika için gerektiği kadar çağırın.
customPolicies.add({
  name: string;                         // zorunlu - benzersiz tanımlayıcı
  description?: string;                 // `failproofai policies` çıktısında gösterilir
  match?: { events?: HookEventType[] }; // etkinlik türüne göre filtrele; tümünü eşleştirmek için atlayın
  fn: (ctx: PolicyContext) => PolicyResult | Promise<PolicyResult>;
});

Karar yardımcıları

İşlevEtkiNe zaman kullanılır
allow()İşleme sessizce izin verİşlem güvenli, mesaj gerekmez
deny(message)İşlemi engelleAgent bu işlemi yapmamalı
instruct(message)Bloklamadan bağlam ekleAgent’a yolunda kalması için ekstra bağlam ver
deny(message) - ileti Claude’a "Blocked by failproofai:" ön eki ile görünür. Tek bir deny tüm diğer değerlendirmeleri kısaltır. instruct(message) - ileti, Claude’un geçerli araç çağrısı için bağlamına eklenir. Tüm instruct iletileri biriktirilir ve birlikte iletilir.
policyParams içinde hint alanı ekleyerek herhangi bir deny veya instruct iletisine ekstra rehberlik ekleyebilirsiniz — kod değişikliğine gerek yoktur. Bu özel (custom/), proje kural (.failproofai-project/) ve kullanıcı kural (.failproofai-user/) politikaları için de çalışır. Ayrıntılar için Yapılandırma → hint bölümüne bakın.

Bilgilendirici izin iletileri

allow(message) işleme izin verir ve Claude’a bilgilendirici bir ileti gönderir. İleti, hook işleyicisinin stdout yanıtında additionalContext olarak iletilir — instruct tarafından kullanılan mekanizmayla aynı, ancak anlamsal olarak farklı: bir uyarı değil, bir durum güncellemesidir.
İşlevEtkiNe zaman kullanılır
allow(message)İzin ver ve Claude’a bağlam gönderBir kontrol geçmesini onaylayın veya bir kontrol 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
  • Fail-open açıklamaları: allow("GitHub CLI not installed, skipping CI check.") — Claude’a bir kontrol neden atlandığını söyler, böylece tam bağlama sahiptir
  • Birden çok ileti birikir: birden çok politika allow(message) döndürürse, tüm iletiler yeni satırlarla birleştirilir ve birlikte iletilir
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.");

    // ... branch 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ç (örn. "Bash", "Write", "Read")
toolInputRecord<string, unknown> | undefinedAracının giriş parametreleri
payloadRecord<string, unknown>Claude Code’dan 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

Etkinlik türleri

EtkinlikNe zaman ateşlenirtoolInput içeriği
PreToolUseClaude bir aracı çalıştırmadan önceAracının girdisi (örn. Bash için { command: "..." })
PostToolUseBir araç tamamlandıktan sonraAracının girdisi + tool_result (çıktı)
NotificationClaude bir bildirim gönderdiğinde{ message: "...", notification_type: "idle" | "permission_prompt" | ... } - hook’lar her zaman allow() döndürmelidir, bildirimleri bloklamaz
StopClaude oturumu sona erdiğindeBoş

Değerlendirme sırası

Politikalar şu sırayla değerlendirilir:
  1. Yerleşik politikalar (tanım sırasında)
  2. customPoliciesPath öğesinden açık özel politikalar (.add() sırasında)
  3. Proje .failproofai/policies/ öğesinden kural politikaları (dosyalar alfabetik, içinde .add() sırası)
  4. Kullanıcı ~/.failproofai/policies/ öğesinden kural politikaları (dosyalar alfabetik, içinde .add() sırası)
İlk deny tüm sonraki politikaları kısaltır. Tüm instruct iletileri biriktirilir ve birlikte iletilir.

Geçişli içe aktarmalar

Özel politika dosyaları göreli yolları kullanan yerel modülleri içe 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 erişilebilen tüm göreli içe aktarmalar çözülür. 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.

Etkinlik türü filtrelemesi

Bir politikanın ne zaman ateşlendiğini sınırlamak için match.events öğesini kullanın:
customPolicies.add({
  name: "require-summary-on-stop",
  match: { events: ["Stop"] },
  fn: async (ctx) => {
    // Yalnızca oturum sona erdiğinde ateşlenir
    // ctx.session.transcriptPath tam oturum günlüğünü içerir
    return allow();
  },
});
Her etkinlik türünde ateşlemek için match öğesini tamamen atlayın.

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

Özel politikalar açık başarısızlık: hatalar hiçbir zaman yerleşik politikaları bloklamaz veya hook işleyicisini çökmez.
BaşarısızlıkDavranış
customPoliciesPath ayarlanmadıAçık özel politika çalışmaz; kural politikaları ve yerleşikler normal şekilde devam eder
Dosya bulunamadıUyarı ~/.failproofai/hook.log öğesine kaydedilir; yerleşikler devam eder
Sözdizimi/içe aktarma hatası (açık)Hata ~/.failproofai/hook.log öğesine kaydedilir; açık özel politikalar atlanır
Sözdizimi/içe aktarma hatası (kural)Hata kaydedilir; bu dosya atlanır, diğer kural dosyaları yine de yüklenir
fn çalışma zamanında hatasıHata kaydedilir; bu hook allow olarak kabul edilir; diğer hook’lar devam eder
fn 10 saniyeden uzun sürerseZaman aşımı kaydedilir; allow olarak kabul edilir
Kural dizini eksikKural politikası çalışmaz; hata yoktur
Özel politika hatalarını ayıklamak için günlük dosyasını izleyin:
tail -f ~/.failproofai/hook.log

Tam örnek: birden çok politika

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

// Agent'i secrets/ dizinine yazmaktan önle
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();
  },
});

// Agent'i yolunda tut: işleme atmadan ö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 plansız 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 çalışmaya hazır politika dosyalarını içerir:
Dosyaİçerik
examples/policies-basic.jsOrtak agent başarısızlık modlarını kapsayan beş başlatıcı politika
examples/policies-advanced/index.jsGelişmiş desenleri: geçişli içe aktarmalar, eşzamansız çağrılar, çıktı temizleme ve oturum sonu hook’ları
examples/convention-policies/security-policies.mjsKural tabanlı güvenlik politikaları (.env yazılarını blokla, git geçmişini yeniden yazmayı önle)
examples/convention-policies/workflow-policies.mjsKural tabanlı iş akışı politikaları (test hatırlatmaları, dosya yazma denetimi)

Açık dosya örneklerini kullanma

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

Kural tabanlı örnekleri kullanma

# Proje düzeyine kopyala
mkdir -p .failproofai/policies
cp examples/convention-policies/*.mjs .failproofai/policies/

# Veya kullanıcı düzeyine kopyala
mkdir -p ~/.failproofai/policies
cp examples/convention-policies/*.mjs ~/.failproofai/policies/
Yükleme komutu gerekli değildir — dosyalar sonraki hook etkinliğinde otomatik olarak seçilir.