العودة إلى التحديثات
New releaseJul 24, 2026

trailmark v0.5.0

بناء والاستعلام عن تمثيل قاعدة بيانات رسومية لشفرة المصدر

مشاركة

Trailmark

CI Mutation Testing

قم بتحليل شيفرة المصدر إلى رسوم بيانية قابلة للاستعلام عن الوظائف والكلاسات والاستدعاءات والتعليقات الدلالية لتحليل الأمان.

يستخدم Trailmark tree-sitter لتحليل AST غير مقيد بلغة معينة و rustworkx لاجتياز الرسوم البيانية عالي الأداء. الرؤية طويلة المدى هي دمج هذا الرسم البياني مع اختبار التحوير والتوجيه بالتغطية للعثور على الفجوات بين الافتراضات وتغطية الاختبار التي يمكن الوصول إليها من مدخلات المستخدم.

كيف يعمل

يعمل Trailmark في ثلاث مراحل: parse و index و query.```mermaid flowchart TD A["Source Files"] --> B["tree-sitter Parser"] B --> C["CodeGraph (nodes + edges)"] C --> D["rustworkx GraphStore"] D --> E["QueryEngine"] E --> F["JSON / Summary / Hotspots"]

classDef src fill:#007bff26,stroke:#007bff,color:#007bff
classDef parse fill:#28a74526,stroke:#28a745,color:#28a745
classDef data fill:#6f42c126,stroke:#6f42c1,color:#6f42c1
classDef query fill:#ffc10726,stroke:#e6a817,color:#e6a817

class A src
class B parse
class C,D data
class E,F query
### 1. التحليل

يقوم المحلل اللغوي المخصص بلغة معينة بجولة في الدليل، ويحلل كل ملف إلى شجرة AST من نوع tree-sitter، ويستخرج:

- **العُقد** — الدوال، الطرق، الصنوف، الهياكل، الواجهات، السمات، التعدادات، الوحدات، النطاقات
- **الحواف** — الاستدعاءات، الوراثة، التنفيذ، الاحتواء، الاستيرادات
- **البيانات الوصفية** — التعليقات التوضيحية للنوع، التعقيد الدوري، الفروع، نصوص التوثيق، أنواع الاستثناءات

### اللغات المدعومة

| اللغة | الامتدادات | البنى الرئيسية |
| --- | --- | --- |
| Python | `.py` | الدوال، الصنوف، الطرق |
| JavaScript | `.js`, `.jsx`, `.mjs`, `.cjs` | الدوال، الصنوف، دوال السهم |
| TypeScript | `.ts`, `.tsx` | الدوال، الصنوف، الواجهات، التعدادات |
| PHP | `.php` | الدوال، الصنوف، الواجهات، السمات |
| Ruby | `.rb` | الطرق، الصنوف، الوحدات |
| C | `.c`, `.h` | الدوال، الهياكل، التعدادات |
| C++ | `.cpp`, `.hpp`, `.cc`, `.hh`, `.cxx`, `.hxx` | الدوال، الصنوف، الهياكل، النطاقات |
| C# | `.cs` | الطرق، الصنوف، الواجهات، الهياكل، التعدادات، النطاقات |
| Java | `.java` | الطرق، الصنوف، الواجهات، التعدادات |
| Go | `.go` | الدوال، الطرق، الهياكل، الواجهات |
| Rust | `.rs` | الدوال، الهياكل، السمات، التعدادات، كتل التنفيذ |
| Solidity | `.sol` | العقود، الواجهات، المكتبات، الدوال، المعدلات، الهياكل، التعدادات |
| Cairo | `.cairo` | الدوال، السمات، الهياكل، التعدادات، كتل التنفيذ، عقود StarkNet |
| Circom | `.circom` | القوالب، الدوال، الإشارات، المكونات |
| Haskell | `.hs` | الدوال، أنواع البيانات، صنوف الأنواع، المثيلات |
| Erlang | `.erl` | الدوال، السجلات، السلوكيات، الوحدات |
| Miden Assembly | `.masm` | الإجراءات، نقاط الدخول، الثوابت، الاستدعاءات |
| Swift | `.swift` | الدوال، الصنوف، الهياكل، التعدادات، البروتوكولات، الامتدادات |
| Objective-C | `.m`, `.mm`, `.h` | دوال C، الصنوف، الطرق (تسمية قائمة على المُحدد) |
| Kotlin | `.kt`, `.kts` | الدوال، الصنوف، الواجهات، صنوف البيانات، الكائنات، الطرق |
| Dart | `.dart` | الدوال، الصنوف، الصنوف المجردة، الطرق، المُنشئون |
| Move | `.move` | الوحدات، الدوال، الاستيرادات، الاستدعاءات المباشرة |
| Tact | `.tact` | العقود، الهياكل، المستقبلون، الدوال |
| Func | `.fc`, `.func` | الدوال، التضمينات، الاستدعاءات المباشرة |
| Sway | `.sw` | واجهات ABI، الهياكل، طرق التنفيذ، الدوال |
| Rego | `.rego` | الحزم، الاستيرادات، قواعد السياسة، استدعاءات القاعدة |
| Proto | `.proto` | الخدمات، استدعاءات الإجراءات عن بُعد (RPCs)، الرسائل، الحقول، التعدادات |
| Thrift | `.thrift` | الخدمات، الدوال، الهياكل، الحقول، التعدادات |
| GraphQL | `.graphql`, `.gql` | أنواع الكائنات، العمليات الجذرية، الحقول، التعدادات |
| SQL | `.sql` | المخططات، الجداول، العروض، الدوال، الإجراءات |```mermaid
flowchart TD
    subgraph "Per-File Parsing"
        F["Source file"] --> TS["tree-sitter AST"]
        TS --> EX["Extract nodes"]
        TS --> EC["Extract call edges"]
        TS --> EB["Count branches"]
        TS --> ET["Resolve types"]
    end

    EX --> CG["CodeGraph"]
    EC --> CG
    EB --> CG
    ET --> CG

    classDef src fill:#007bff26,stroke:#007bff,color:#007bff
    classDef parse fill:#28a74526,stroke:#28a745,color:#28a745
    classDef extract fill:#ffc10726,stroke:#e6a817,color:#e6a817
    classDef data fill:#6f42c126,stroke:#6f42c1,color:#6f42c1

    class F src
    class TS parse
    class EX,EC,EB,ET extract
    class CG data

تتبع معرفات العقد النمط module:function أو module:Class أو module:Class.method للبحث غير الملتبس. يقوم تحليل الدليل بحل استدعاءات عبر الملفات البسيطة عندما يوجد تعريف فريد؛ أما الاستدعاءات عبر الملفات الغامضة فتترك عند هدفها الأصلي بأفضل جهد وتُوسم بـ uncertain. توسم ثقة الحافة بأنها certain (استدعاءات مباشرة، self.method()) أو inferred (الوصول إلى السمات على كائنات غير self) أو uncertain (التوزيع الديناميكي أو الحل الغامض).

2. الفهرس

يقوم GraphStore بتحميل CodeGraph في PyDiGraph من rustworkx ويبني تعيينات ثنائية الاتجاه للمعرفات/الفهارس للتنقل السريع.

3. الاستعلام

يوفر QueryEngine واجهة برمجة تطبيقات عالية المستوى فوق الرسم البياني المفهرس:

MethodDescription
callers_of(name)المستدعون المباشرون للهدف المسمى
callees_of(name)المستدعى المباشر من المصدر المسمى
ancestors_of(name)كل دالة يمكنها الوصول إلى الهدف بشكل متعدي (شريحة لأعلى)
reachable_from(name)كل دالة يمكن الوصول إليها بشكل متعدي من المصدر
paths_between(src, dst)كل مسارات الاستدعاء البسيطة بين عقدتين
connect_subgraphs(source, target)المسارات التي تربط بين رسمين بيانيين فرعيين مسمى
entrypoint_paths_to(name)المسارات من أي نقطة دخول تم اكتشافها إلى الهدف
attack_surface()نقاط الدخول الموسومة بمستوى الثقة وقيمة الأصول وسمات المحلل عند وجودها
complexity_hotspots(n)الدوال التي يكون تعقيدها الدوري ≥ n
functions_that_raise(exc)الدوال التي تتضمن قائمة الاستثناءات المكتشفة بواسطة المحلل exc
generic_parameters(name)معلمات النوع العام المعلنة بواسطة عقدة
type_references(name)مراجع النوع للمعاملات والإرجاع والاستثناءات والحدود العامة
annotate(name, kind, description, source)إضافة تعليق دلالي إلى عقدة
annotations_of(name, kind=None)الحصول على تعليقات لعقدة، مرشحة حسب النوع اختيارياً
nodes_with_annotation(kind)كل عقدة موسومة بنوع التعليق المعطى
clear_annotations(name, kind=None)إزالة التعليقات من عقدة
diff_against(other)الفرق الهيكلي بين رسم هذا المحرك وآخر
preanalysis()تشغيل تمريرات التحليل المسبق المضمنة وتخزين التعليقات/الرسومات الفرعية
augment_sarif(path)دمج نتائج SARIF في الرسم البياني
augment_weaudit(path)دمج نتائج weAudit في الرسم البياني
augment_binary(path)دمج ملف JSON لتحليل ثنائي خارجي
findings(kind=None)إرجاع العقد التي تحمل تعليقات من نوع النتائج
subgraph(name)إرجاع العقد في رسم فرعي مسمى
subgraph_edges(name)إرجاع الحواف المستحثة داخل رسم فرعي مسمى
subgraph_names()سرد كل رسم فرعي مسمى موجود حالياً على الرسم البياني
summary()عدد العقد، عدد الحواف، التبعيات
to_json()تصدير كامل للرسم البياني

نموذج البيانات```mermaid

classDiagram class CodeGraph { language: str root_path: str nodes: dict[str, CodeUnit] edges: list[CodeEdge] annotations: dict[str, list[Annotation]] entrypoints: dict[str, EntrypointTag] dependencies: list[str] add_annotation(node_id, annotation) clear_annotations(node_id, kind=None) merge(other) }

class CodeUnit {
    id: str
    name: str
    kind: NodeKind
    location: SourceLocation
    parameters: tuple[Parameter]
    return_type: TypeRef
    exception_types: tuple[TypeRef]
    cyclomatic_complexity: int
    branches: tuple[BranchInfo]
    docstring: str
}

class CodeEdge {
    source_id: str
    target_id: str
    kind: EdgeKind
    confidence: EdgeConfidence
}

class Annotation {
    kind: AnnotationKind
    description: str
    source: str
}

class EntrypointTag {
    kind: EntrypointKind
    trust_level: TrustLevel
    description: str
    asset_value: AssetValue
}

CodeGraph "1" *-- "*" CodeUnit
CodeGraph "1" *-- "*" CodeEdge
CodeGraph "1" *-- "*" Annotation
CodeGraph "1" *-- "*" EntrypointTag
**أنواع العُقد:** `function`, `method`, `class`, `module`, `struct`, `interface`, `trait`, `enum`, `namespace`, `contract`, `library`, `template`, `proxy`

**أصول العُقد:** `source`, `proxy`, `binary`, `synthetic`

**أنواع الحواف:** `calls`, `inherits`, `implements`, `contains`, `imports`, `resolves_to`, `type_uses`, `specializes`, `corresponds_to`

**ثقة الحافة:** `certain`, `inferred`, `uncertain`

يتم تجسيد الاستدعاءات غير المحلولة كعُقد وكيلة مثل
`proxy.unresolved:<raw-symbol>` بحيث يمكن لنتائج الاجتياز إظهار مكان فقدان التحليل المصدر للدقة بدلاً من إسقاط تلك الحافة بصمت. يدعم التحليل الثنائي استيراد رسوم بيانية للاستدعاءات بتنسيق JSON من مصادر خارجية؛ لا يقوم Trailmark بتفكيك الملفات التنفيذية بنفسه.

### مثال على رسم بياني

بإعطاء كود بايثون التالي:```python
class Auth:
    def verify(self, token: str) -> bool:
        return self._check_sig(token)

    def _check_sig(self, token: str) -> bool:
        ...

def handle_request(req: Request) -> Response:
    auth = Auth()
    if auth.verify(req.token):
        return process(req)
    return deny()

Trailmark ينتج رسمًا بيانيًا مثل:```mermaid graph TD HR["handle_request"] -->|calls| AV["Auth.verify"] HR -->|calls| P["process"] HR -->|calls| D["deny"] AV -->|calls| CS["Auth._check_sig"] A["Auth"] -->|contains| AV A -->|contains| CS

classDef fn fill:#007bff26,stroke:#007bff,color:#007bff
classDef cls fill:#6f42c126,stroke:#6f42c1,color:#6f42c1

class HR,P,D fn
class A,AV,CS cls
## التثبيت

الأمثلة أدناه تتبع فرع التطوير الحالي. للحصول على أحدث حزمة منشورة، قم بالتثبيت من PyPI. للحصول على مجموعة الميزات الدقيقة الموضحة هنا، قم بالتثبيت من checkout وتشغيل الأوامر عبر `uv run`.```bash
# Latest published release
uv pip install trailmark

# Current checkout / development branch
uv sync --all-groups

يتطلب Python ≥ 3.12.

يستخدم Trailmark حزمة tree-sitter-language-pack لمعظم القواعد النحوية. تستخدم الإصدارات الحالية مخزن الشهادات الخاص بالمنصة لتنزيل القواعد النحوية. في بيئات التفتيش على TLS أو البيئات غير المتصلة، قم بتعبئة ذاكرة التخزين المؤقت للحزم مسبقًا باستخدام python -c "import tree_sitter_language_pack as p; p.download_all()" على منصة متطابقة، ثم انسخ دليل ذاكرة التخزين المؤقت tree-sitter-language-pack الناتج إلى الجهاز الهدف. يتم أيضًا احترام الـ HTTPS_PROXY. يتم شحن القاعدة النحوية لـ SQL كاعتماد لعجلة tree-sitter-sql ولا تستخدم تلك الذاكرة المؤقتة.

Usage```bash

Report the installed version

trailmark --version # or: trailmark -V trailmark version # subcommand form

Full JSON graph (Python, the default)

trailmark analyze path/to/project

Analyze a different language

trailmark analyze --language rust path/to/project trailmark analyze --language javascript path/to/project

Polyglot: auto-detect and merge every supported language found in the

tree, or pass an explicit comma-separated list.

trailmark analyze --language auto path/to/project trailmark analyze --language python,rust,solidity path/to/project

Summary statistics

trailmark analyze --summary path/to/project

Complexity hotspots (threshold >= 10)

trailmark analyze --complexity 10 path/to/project

Augment the graph with external findings (SARIF from static analyzers,

weAudit findings from the VS Code extension). Each --sarif / --weaudit

flag is repeatable. Add --json to print the augmented graph.

trailmark augment --sarif results.sarif path/to/project trailmark augment --weaudit findings.json path/to/project trailmark augment --sarif a.sarif --sarif b.sarif --json path/to/project

List detected entrypoints (attack surface). Uses heuristic detection

(main() functions, pyproject.toml [project.scripts]) plus an optional

override file at .trailmark/entrypoints.toml (see below).

trailmark entrypoints path/to/project trailmark entrypoints --json path/to/project

Structural diff between two code graphs. Accepts directory paths or

git refs (branches, tags, commits). Surfaces added/removed nodes,

call-edge changes, and — most usefully — attack-surface changes.

trailmark diff before/ after/ trailmark diff --repo . main HEAD # compare git refs trailmark diff --json before/ after/ # machine-readable output

Generate a Mermaid diagram from the code graph. --type is required; the

choices are call-graph, class-hierarchy, module-deps, containment,

complexity, and data-flow. Use --focus to scope large graphs.

trailmark diagram --target path/to/project --type call-graph trailmark diagram -t path/to/project -T call-graph -f parse_file --depth 3 trailmark diagram -t path/to/project -T complexity --threshold 5 --direction LR

### Entrypoint detection

يقوم Trailmark تلقائيًا بتعبئة `graph.entrypoints` بحيث يكون لدى `attack_surface()` وانتشار التلوث وعبور حدود الامتيازات بيانات للعمل بها. يتم الكشف في أربع طبقات، كل منها يتجاوز السابقة:

1. **الاستدلال العام `main`.** أي دالة مسماة `main` في أي لغة. موسومة `user_input` / `trusted_internal` / `low`.
2. **فحص واعي بالإطار.** أنماط الديكورات والسمات والرؤية حسب اللغة — انظر الجدول أدناه.
3. **`pyproject.toml [project.scripts]`.** تحصل أهداف CLI الصريحة على تصنيف ثقة/أصل مُرقى.
4. **ملف التجاوز المحلي للمستودع.** نقاط الدخول المُدارة يدويًا في `.trailmark/entrypoints.toml` تفوز دائمًا.

Framework coverage:

| اللغة | الأطر المكتشفة |
| --- | --- |
| Python | Flask, FastAPI, aiohttp, Click, Typer, Celery |
| JavaScript / TypeScript | NestJS, Next.js (App Router + Pages API), AWS Lambda |
| Java | Spring MVC / WebFlux, JAX-RS, Kafka listeners, servlets |
| C# | ASP.NET Core, Azure Functions |
| PHP | Symfony `#[Route]` attributes + legacy annotations |
| Rust | actix-web, rocket, FFI exports (`#[no_mangle]`, `pub extern "C"`), async-main attributes |
| Solidity | `external` / `public` visibility |
| Cairo / StarkNet | `#[external]`, `#[view]`, `#[l1_handler]`, `#[constructor]` |
| Circom | `component main` declarations |
| Miden Assembly | `export.<name>` directives |
| Haskell | top-level `main ::` / `main =` |
| Erlang | functions listed in `-export([...])` |
| Swift | `@main` app attribute |
| Objective-C | `UIApplicationDelegate` lifecycle selectors (e.g. `application:openURL:options:`) |
| Kotlin | Spring MVC / WebFlux annotations (shared with Java), Android component lifecycle methods (`onCreate`, `onReceive`, `onBind`, ...) |
| Dart | `@pragma('vm:entry-point')` native-callable markers |
| Go | `http.HandleFunc` / `http.Handle` stdlib registrations, gin/chi/echo-style `<router>.GET/POST/...` handler registrations |
| Ruby | Rails controller actions (classes inheriting `ApplicationController` / `ActionController::*`), Sidekiq worker `perform` methods |
| C / C++ | `extern "C"` linkage, `__attribute__((visibility("default")))`, `__declspec(dllexport)` |

بالنسبة لأي شيء تفوته الاستدلالات، قم بتعريف نقاط الدخول بشكل صريح في `.trailmark/entrypoints.toml` في جذر المشروع. يدعم الملف كلاً من الإدخالات أحادية العقدة والقائمة على القواعد:```toml
# Single-node entry
[[entrypoint]]
node = "my_module:handle_request"  # node id, or "module.path:function"
kind = "api"                       # user_input | api | database | file_system | third_party
trust = "untrusted_external"       # untrusted_external | semi_trusted_external | trusted_internal
asset_value = "high"               # high | medium | low
description = "HTTP POST /auth"

# Rule: every PHP script under public_html/ is a web-exposed entrypoint.
[[entrypoint]]
file_glob = "public_html/**/*.php"
kind = "user_input"
trust = "untrusted_external"
asset_value = "high"
description = "Web-exposed PHP script"

# Rule: any function that takes a PSR-7 request object.
[[entrypoint]]
param_type = "ServerRequestInterface"
kind = "api"
trust = "untrusted_external"
asset_value = "high"
description = "PSR-7 HTTP handler"

# Rule: functions named `handle_*`.
[[entrypoint]]
name_regex = "^handle_"
kind = "api"
trust = "untrusted_external"

# Rule: conditions compose with AND — web.py files AND name starts with handle_.
[[entrypoint]]
file_glob = "public/*.py"
name_regex = "^handle_"
kind = "api"
trust = "untrusted_external"

الإدخالات اللاحقة تتجاوز الإدخالات السابقة عندما تضع قاعدتان علامة على نفس العقدة، لذا ضع القواعد العامة أولاً والتصحيحات المحددة بعد ذلك.

انظر docs/entrypoint-patterns.md للحصول على المرجع الكامل، بما في ذلك الأطر التي لم يتم تنفيذها بعد (Express / Koa / Fastify، Laravel، Cobra، axum، warp، clap، وغيرها) مع أنماط جاهزة للـ grep يمكن للمساهمين استخدامها لإضافة كاشفات جديدة.

الكشف عن Solidity يستخدم بيانات وصف المحلل اللغوي بدلاً من تعبيرات regex الخاصة بالتوقيع. يتم استبعاد إعلانات الواجهات وتقوم وظيفة تجاوز مشتقة بإلغاء تنفيذ القاعدة الأساسية المطابقة. تبقى الوظائف الملموسة public و external نقاط دخول، بما في ذلك وظائف view و pure؛ يتم إرجاع سماتها solidity_visibility و solidity_mutability بواسطة attack_surface() حتى يتمكن المتصلون من تمييز التعرض للقراءة فقط. تتضمن attack_surface() سمات نقطة الدخول الخاصة بالمحلل اللغوي عندما تكون مرتبطة بعقدة الرسم البياني الأساسية.

روابط عبر اللغات وخارجية

يدمج التحليل متعدد اللغات رسومًا بيانية للغات، ولكن العديد من علاقات RPC و FFI والعملية الفرعية والمضيف/العقد غير مرئية في بناء جملة المصدر. قم بتعريف هذه بشكل حتمي في .trailmark/links.toml:```toml [[link]] source = "backend:submit" target = "contract:Verifier.verify" kind = "calls" # defaults to calls confidence = "certain" # defaults to inferred description = "JSON-RPC eth_call"

[[link]] source = "backend:notify" target = "payments-webhook" external = true # required when either endpoint is unresolved

قد تكون المراجع معرفات عقدة دقيقة أو أسماء/لواحق فريدة. المراجع الغامضة،
نقاط النهاية الداخلية غير المعروفة، قيم التعداد غير الصالحة، و TOML غير الصحيح يثير
`ValueError`. يتيح تعيين `external = true` صراحةً نقاط النهاية غير المحلولة
ويُنشئ عقد وكيل. هذا الملف هو واجهة تكوين عامة مستقرة.

### قيود التحليل

- `entrypoint_paths_to()` يبلغ عن إمكانية الوصول عبر رسم بياني للاستدعاءات، وليس تدفق بيانات
  يتحكم به المهاجم. استخدم نتائج التلوث من التحليل المسبق كإشارة منفصلة تقريبية؛ Trailmark
  لا يقوم بعد بتحليل التلوث عبر الإجراءات.
- TypeScript يحل الاستدعاءات المباشرة والمستقبلات المباشرة المعينة بـ
  `new ConcreteClass()`. توزيع الواجهة من خلال المانيفستات، أسماء الخصائص المحسوبة،
  حاويات حقن التبعية، والآليات الديناميكية الأخرى يظل بأفضل جهد.
- دعم SQL موجه نحو PostgreSQL ويستخرج المخططات، الجداول، العروض،
  الدوال، الإجراءات، وتبعيات الروتين/العرض. إنه ليس مدققًا كاملاً لصيغة SQL
  أو محلل دلالات استعلام.

### واجهة برمجة التطبيقات البرمجية```python
from trailmark.parse import parse_directory, parse_file
from trailmark.query.api import QueryEngine

# Parse-only API: get the raw CodeGraph without building GraphStore/QueryEngine.
graph = parse_file("path/to/file.py")
graph = parse_directory("path/to/project", language="auto")

# Single-language (default) or auto-detect + merge across all languages
engine = QueryEngine.from_directory("path/to/project")
engine = QueryEngine.from_directory("path/to/project", language="auto")
engine = QueryEngine.from_directory("path/to/project", language="python,rust")

# Direct neighbors
engine.callers_of("handle_request")
engine.callees_of("handle_request")

# Transitive slicing — who could reach this sink, or what could it reach?
engine.ancestors_of("Auth._check_sig")
engine.reachable_from("handle_request")

# Attack-surface paths from any detected entrypoint
engine.entrypoint_paths_to("Auth._check_sig")

# All call paths between two nodes
engine.paths_between("handle_request", "Auth._check_sig")

# Functions with cyclomatic complexity >= 10
engine.complexity_hotspots(10)

# What functions can raise a given exception? (uses parser-detected
# exception_types; no runtime tracing required)
engine.functions_that_raise("PermissionError")

# Add and query semantic annotations
from trailmark.models.annotations import AnnotationKind

engine.annotate(
    "handle_request",
    AnnotationKind.ASSUMPTION,
    "Caller has already authenticated the session token",
    source="llm",
)
engine.annotations_of("handle_request")
engine.nodes_with_annotation(AnnotationKind.FINDING)

# Diff against an earlier snapshot of the same codebase
before = QueryEngine.from_directory("before/")
diff = engine.diff_against(before)
# diff contains: summary_delta, nodes {added/removed/modified},
# edges {added/removed}, entrypoints {added/removed/modified}

# Run the built-in audit-oriented preanalysis passes
engine.preanalysis()
engine.findings()
engine.subgraph_names()

# Programmatic augmentation hooks for external tooling
engine.augment_sarif("results.sarif")
engine.augment_weaudit("findings.json")

NodeKind.SCHEMA, TABLE, VIEW, و PROCEDURE مضافة في الإصدار v0.5.0؛ يجب على المستهلكين الذين يطابقون قيم التعداد بشكل شامل إضافة حالات لها.

التطوير```bash

Install package and dev dependencies

uv sync --all-groups

Lint and format

uv run ruff check --fix uv run ruff format

Type check

uv tool install ty && ty check

Tests

uv run pytest -q tests/

Mutation testing (on macOS, set this env var to avoid rustworkx fork segfaults)

OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES uv run mutmut run

## الترخيص

Apache-2.0

الفئات