
AI एजेंटों के लिए छेड़छाड़-रोधी ऑडिट ट्रेल: हैश-चेन्ड Runtime Records, डिपेंडेंसी-मुक्त, जिसे कोई भी सत्यापित कर सकता है।
छेड़छाड़-स्पष्ट AI एजेंट्स के लिए ऑडिट ट्रेल्स — हैश-चेन्ड Runtime Records, जिन्हें एक Runtime Report के रूप में प्रस्तुत किया जाता है जिसे आपके ग्राहक स्वयं जाँच सकते हैं।
आपके एजेंट द्वारा की गई हर क्रिया (टूल कॉल्स, मॉडल कॉल्स, डेटा एक्सेस, अनुमोदन) एक Runtime Record बन जाती है एक append-only, हैश-चेन्ड लॉग में; Runtime Report उस चेन को एक स्व-सत्यापनकारी HTML पेज के रूप में प्रस्तुत करता है। चेन का चेकपॉइंट रखने वाला कोई भी पक्ष यह सत्यापित कर सकता है कि उसके पीछे के रिकॉर्ड्स कभी बदले नहीं गए, बिना उस पर भरोसा किए जिसने उन्हें बनाया — वह चेकपॉइंट ही भार वहन करने वाला हिस्सा है: चेन अकेले ही रिकॉर्डर चलाने वाले पक्ष को छोड़कर सभी के विरुद्ध छेड़छाड़-स्पष्ट है (LIMITS.md §1)। जब किसी ग्राहक की सुरक्षा टीम पूछे "आपके एजेंट ने हमारे डेटा के साथ क्या किया?", तो आप उन्हें एक पैराग्राफ के बजाय एक लिंक थमा देते हैं। सुरक्षा समीक्षाएँ पहले से ही SOC 2 चेकलिस्ट के बगल में AI प्रश्न पूछती हैं — और तेजी से ये प्रश्न ISO 42001, EU AI Act के रिकॉर्ड-कीपिंग अनुच्छेदों, और ग्राहकों की अपनी प्रश्नावलियों से आते हैं। आज एक लिखित आश्वासन अभी भी पास हो जाता है। इस परियोजना के पीछे का दाँव यह है कि यह ज्यादा समय तक नहीं चलेगा।
Help Net Security में प्रमुखता से प्रस्तुत (अगस्त 2026)।
रिकॉर्ड प्रारूप खुला और लागू करने के लिए निःशुल्क है। यह पैकेज संदर्भ कार्यान्वयन है: रिकॉर्डर, सत्यापनकर्ता, विटनेस क्लाइंट, और रिपोर्ट सर्वर।
halo-record का उपयोग कर रहे हैं, या इसके बारे में सोच रहे हैं? मुझे बताएं आप कौन हैं और किसलिए → Who's using halo-record?
आपसे कहा जा रहा है कि आप अपने एजेंट के अंदर एक रिकॉर्डर लगाएं। आपको इसे विश्वास पर नहीं लेना चाहिए:
pip install halo-record ठीक एक पैकेज इंस्टॉल करता है।summaries=False) कोई सारांश नहीं रखता। रिडैक्शन बेस्ट-एफर्ट है (सामान्य सीक्रेट और PII प्रारूपों पर रेगेक्स प्लस एक एन्ट्रॉपी कैच-ऑल): इसे डिफेंस-इन-डेप्थ मानें, गारंटी नहीं। summary से परे आपके द्वारा दिए गए आउटकम फ़ील्ड्स जैसे हैं वैसे सील हो जाते हैं (LIMITS §13)।प्रत्येक परत क्या साबित करती है — इस परियोजना में भार वहन करने वाला अंतर (LIMITS.md §1): आपके पास स्वयं की चेन साबित करती है कि रिकॉर्ड्स संपादित नहीं किए गए, उस हेड के सापेक्ष जो किसी के पास पहले से है; केवल ऑपरेटर के बाहर रखे गए चेकपॉइंट्स साबित करते हैं कि कोई हटाया नहीं गया; और कोई हैश साबित नहीं करता कि हर क्रिया कैप्चर की गई थी।
इंस्टॉल करने से पहले एक देखें: एक नमूना Runtime Report — काल्पनिक डेटा, असली चेन, और यह आपके ब्राउज़र में आपके देखते-देखते स्वयं को पुनः सत्यापित करता है।
किसी एजेंट की आवश्यकता नहीं। uv के साथ, कुछ भी इंस्टॉल करने की जरूरत नहीं:``` uvx --from halo-record halo demo --serve
या क्लासिक तरीका:```
pip install halo-record
halo demo --serve
या तो एक काल्पनिक सपोर्ट-एजेंट विक्रेता को दो ग्राहकों के साथ स्कैफोल्ड करता है, चेन को साक्षी बनाता है (ऑपरेटर के बाहर एक के लिए स्थानीय गवाह फ़ाइल के साथ — देखें LIMITS.md §1), उनकी गेटेड Runtime Reports सर्व करता है, और आपके ब्राउज़र में ऑपरेटर कंसोल खोलता है। फिर टैम्पर टेस्ट आज़माएँ: .jsonl फ़ाइलों में से एक से एक पंक्ति हटाएँ और पुनः लोड करें। रिपोर्ट इसे पकड़ लेती है।
सीमा पर एक पंक्ति:```python from halo_record import trace
agent = trace(run_my_agent, profile="my-agent", log="audit.jsonl") # wraps your entrypoint; records the run boundary to ./audit.jsonl — add record_call() or a framework adapter at each tool boundary to capture individual calls
`from halo import ...` सुविधा शिम भी शिप होती है — लेकिन PyPI पर `halo` नाम एक असंबंधित टर्मिनल-स्पिनर पैकेज का है, और यदि वह पैकेज इंस्टॉल है तो इम्पोर्ट में वही जीतता है। `halo_record` स्पष्ट है, इसलिए उदाहरण इसे उपयोग करते हैं।
`log=` के बिना, रिकॉर्ड `~/.halo/my-agent.jsonl` में जाते हैं (प्रति एजेंट एक चेन)। रैपर रन सीमा को सील करता है; साक्ष्य प्रति-कॉल रिकॉर्ड में रहता है। उन्हें एक फ्रेमवर्क एडाप्टर (नीचे मैट्रिक्स) से कैप्चर करें — या स्पष्ट रूप से, जो यह भी दिखाता है कि प्रतिनिधिमंडल कैसे लिंक होता है:```python
from halo_record import Recorder, record_call
rec = Recorder("audit.jsonl")
with record_call(rec, "crm.lookup", {"account": "acct-9"}) as call: # one sealed record per tool call
call.result = crm.lookup("acct-9")
with record_call(rec, "payments.refund", {"amount": 120},
parent_id=rec.last_record_id()) as call: # child links to the action that spawned it
call.result = payments.refund(120)
फिर रिपोर्ट रेंडर करें:``` halo report audit.jsonl -o report.html # one chain -> self-verifying HTML halo serve ./records --port 8721 # all tenants, gated per customer
The quickstart तब समाप्त होता है जब आप ब्राउज़र में अपने स्वयं के agent की Runtime Report देख रहे होते हैं। यदि आपको एक JSONL फ़ाइल मिली और कोई रिपोर्ट नहीं मिली, तो कुछ गड़बड़ है: एक issue खोलें।
### The verification block
यदि किसी guardrail या policy layer ने कार्रवाई की जाँच की, तो उसका निर्णय रिकॉर्ड पर सवार हो सकता है — एक optional block जो रिकॉर्ड करता है कि gate ने क्या तय किया, जिसे हर अन्य field की तरह hash chain में सील कर दिया जाता है:```python
from halo_record import build
build("tool_call", "security", tool="payments.refund",
verification={"status": "allowed", "verifier": "gate/1.2",
"policy_ref": "sha256:1f3a...",
"checked_at": "2026-08-01T12:00:00Z"})
जो रिकॉर्ड में इस प्रकार सील हो जाता है:```json "verification": {"status": "allowed", "verifier": "gate/1.2", "policy_ref": "sha256:1f3a...", "checked_at": "2026-08-01T12:00:00Z"}
`record_call(...)` वही `verification=` कीवर्ड स्वीकार करता है। ब्लॉक के भीतर `status` आवश्यक है; `verifier`, `policy_ref`, और `checked_at` वैकल्पिक हैं। प्रत्येक स्टेटस का क्या अर्थ है:
| स्टेटस | गेट क्या रिपोर्ट करता है | क्या क्रिया निष्पादित हुई? |
|---|---|---|
| `allowed` | इसने क्रिया की अनुमति दी | हाँ — क्रिया आगे बढ़ी |
| `blocked` | इसने क्रिया को अस्वीकार किया | यह इंटीग्रेशन द्वारा निर्धारित होता है, इस फ़ील्ड द्वारा नहीं — एक रिकॉर्ड अभी भी एक परिणाम वहन कर सकता है, और एक ब्लॉक अपने आप में गैर-निष्पादन सिद्ध नहीं करता |
| `modified` | इसने निष्पादन से पहले क्रिया को बदल दिया — `action.input` क्रिया को **निष्पादित रूप में**, संशोधन के बाद, वर्णित करता है | हाँ, परिवर्तित रूप में |
| `unverified` | यह चला (या इससे परामर्श लिया गया) लेकिन कोई निर्धारण नहीं किया — एक अनुपस्थित ब्लॉक से भिन्न, जिसका अर्थ है कि कोई सत्यापन दावा बिल्कुल नहीं किया गया | हाँ — क्रिया बिना किसी निर्णय के आगे बढ़ी |
यह ब्लॉक ऑपरेटर के इंटीग्रेशन कोड द्वारा प्रदान किया जाता है और रिकॉर्ड करता है कि यह रिपोर्ट करता है कि गेट ने क्या कहा — वही विश्वास मुद्रा जो `principal` की है (देखें [LIMITS](https://github.com/bkuan001/halo-record/blob/main/LIMITS.md#11-verification-status-is-the-gates-report-not-halos-finding))। सीलिंग सिद्ध करती है कि स्टेटस को बाद में संपादित नहीं किया गया; यह सिद्ध नहीं करती कि जाँच हुई, कि निर्णय सही था, या कि एक अवरुद्ध क्रिया निष्पादित नहीं हुई। यह स्वतंत्र सत्यापन नहीं है।
`policy_ref` को साक्ष्य के रूप में उपयोग करने योग्य बनाने के लिए, नियमसेट का एक कंटेंट हैश उपयोग करें और नियमसेट आर्टिफैक्ट को बनाए रखें — एक अनसुलझा लेबल फ़ील्ड को सजावटी बना देता है।
## जो आप पहले से चलाते हैं उससे कनेक्ट करें
| सीमा पर कैप्चर किया गया | मौजूदा टेलीमेट्री से अंतर्ग्रहित |
|---|---|
| नेटिव रिकॉर्डर (`from halo_record import trace`) | OpenTelemetry GenAI स्पैन |
| MCP इंटरसेप्टर | LiteLLM कॉलबैक |
| LangChain / LangGraph कॉलबैक | Langfuse एक्सपोर्ट |
| OpenAI Agents SDK हुक | कोई भी गेटवे / रिवर्स-प्रॉक्सी लॉग |
| Claude Agent SDK हुक | Claude Code और Codex CLI `PostToolUse` हुक (टूल चलने के बाद फायर होते हैं) |
फ्रेमवर्क एडाप्टर और अंतर्ग्रहण पथ प्रत्येक रिकॉर्ड को एक `source` टैग के साथ मुहर लगाते हैं, इसलिए रिपोर्ट बताती है कि प्रत्येक साक्ष्य कैसे एकत्र किया गया था। कैप्चर किए गए और अंतर्ग्रहित रिकॉर्ड एक ही श्रृंखला में रहते हैं।
LangChain / LangGraph के लिए, यह एक कॉलबैक हैंडलर है:```python
from halo_record import Recorder
from halo_record.integrations.langchain import HaloCallbackHandler
recorder = Recorder("audit.jsonl")
result = my_chain.invoke(inputs, config={"callbacks": [HaloCallbackHandler(recorder)]}) # every tool call becomes a record
MCP के लिए, एक कॉल क्लाइंट सत्र को रैप करती है — और फिर कोई भी MCP-उपयोग करने वाला एजेंट हर टूल कॉल के लिए रिकॉर्ड उत्सर्जित करता है, चाहे उसे कोई भी फ्रेमवर्क चलाए:```python from halo_record.integrations.mcp import instrument_client_session
instrument_client_session(session, Recorder("audit.jsonl"), server="stripe") # every session.call_tool() is now recorded
For gateway या proxy logs (Cloudflare AI Gateway, Portkey, model के सामने nginx), एक log row को chain में map करें — स्पष्ट रूप से ingested के रूप में tagged, boundary-captured नहीं:```python
from halo_record.integrations.gateway import record_log
record_log(Recorder("audit.jsonl"), {"tool": "gen_ai:gpt-4o", "model": "gpt-4o", "status": 200, "subject": "acme-corp"})
OpenTelemetry GenAI spans उत्सर्जित करने वाला कोई भी साधन (CrewAI, LlamaIndex, और OTel instrumentation वाले अधिकांश agent frameworks) OTel adapter के माध्यम से chain में शामिल हो जाता है, और TypeScript package Vercel AI SDK और JS agent ecosystem के लिए native adapters प्रदान करता है। आपके stack के लिए adapter नहीं है? एक issue खोलें। अधिकांश adapters लगभग सौ पंक्तियों के होते हैं।
Claude Code हर tool call के बाद एक PostToolUse hook फायर करता है। इसे halo hook पर point करें और हर action — file writes, shell commands, MCP connector calls — एक local chain में record बन जाता है। कोई code changes नहीं; एक settings entry:```json
{
"hooks": {
"PostToolUse": [
{"matcher": "*", "hooks": [{"type": "command", "command": "halo hook"}]}
]
}
}
इसे `~/.claude/settings.json` में जोड़ें और रिकॉर्ड `~/.halo/audit.jsonl` में दर्ज हो जाते हैं (`$HALO_LOG` से ओवरराइड करें)। जो शुद्ध-ऑर्केस्ट्रेशन टूल्स किसी डेटा, नेटवर्क, या बाहरी स्टेट को नहीं छूते, उन्हें छोड़ दिया जाता है — चेन ट्रस्ट-बाउंड्री क्रियाओं को रिकॉर्ड करती है, सोच को नहीं। सारांश के बिना कंटेंट हैश रिकॉर्ड करने के लिए `HALO_HASH_ONLY=1` सेट करें। प्रत्येक रिकॉर्ड को उस एजेंट बिल्ड से बाइंड करने के लिए `HALO_AGENT_VERSION` (और वैकल्पिक रूप से `HALO_AGENT_MODEL`) सेट करें जिसने उसे उत्पन्न किया — जब कोई ऑडिटर किसी दिए गए विंडो में चल रहे वर्ज़न के बारे में पूछता है, तो एक्सपोर्ट स्मृति के बजाय कॉलम के अनुसार उत्तर देता है।
Codex CLI समान इवेंट शेप के साथ वही लाइफसाइकल हुक्स शिप करता है (हुक्स डिफ़ॉल्ट रूप से चालू हैं)। इसे `~/.codex/hooks.json` में जोड़ें और Codex के शेल कमांड, `apply_patch` एडिट्स, और MCP कॉल्स उसी चेन में दर्ज हो जाते हैं:```json
{
"hooks": {
"PostToolUse": [
{"matcher": ".*", "hooks": [{"type": "command", "command": "halo hook"}]}
]
}
}
The hook दोनों को event से अलग करता है (Codex turn_id और model जोड़ता है) और प्रत्येक record को claude-code या codex लेबल करता है; किसी एक को बाध्य करने के लिए HALO_HOOK_AGENT सेट करें। दोनों ingested tier हैं: एक PostToolUse hook tool चलने के बाद fire होता है, इसलिए record उसी से बनाया जाता है जो harness रिपोर्ट करता है।
यदि आपको रिपोर्ट से यह उत्तर चाहिए कि "यह run किन rules के अंतर्गत हुआ?", तो session के लिए effective authority के JSON snapshot पर HALO_AUTHORITY_FILE सेट करें। इसे privacy-safe रखें: hashes और refs, raw prompts, private policy text, secrets, या पूर्ण tool schemas नहीं — ज्ञात secret formats seal time पर mask किए जाते हैं, लेकिन hashes और refs बिना छेड़े पास हो जाते हैं और free-form text detect नहीं होता (देखें LIMITS §6)। snapshot_id का पुनः उपयोग केवल तब करें जब underlying authority अपरिवर्तित हो; समान id और अपरिवर्तित content वाले क्रमागत records compact किए जाते हैं — बदले हुए content पर पुनः उपयोग किया गया id पूर्ण रूप में संग्रहीत होता है, एक notice के साथ।```json
{
"snapshot_id": "auth_2026_07_08T1100Z",
"captured_at": "2026-07-08T11:00:00Z",
"scope": "session",
"workspace": {"path_hash": "sha256:...", "git_commit": "abc1234"},
"refs": [
{"kind": "project_rules", "id": "CLAUDE.md", "hash": "sha256:...", "loaded": true, "truncated": false},
{"kind": "mcp_tool_registry", "id": "filesystem", "hash": "sha256:..."}
],
"omissions": [{"kind": "private_policy", "reason": "customer_secret", "hash": "sha256:..."}],
"stale_if": ["project_rules_hash_changed", "mcp_tool_registry_hash_changed"]
}
| `-s` | `--server` | Server URL (default: `http://localhost:8080`) |
| `-t` | `--token` | API token for authentication |
| `-o` | `--output` | Output format: `json`, `yaml`, `table` (default: `table`) |
| `-v` | `--verbose` | Enable verbose output |
| `-q` | `--quiet` | Suppress non-essential output |
| `-h` | `--help` | Show help message |
| `-V` | `--version` | Show version information |
### उदाहरण
```bash
# List all scans
kitploit-cli scan list
# Get details of a specific scan
kitploit-cli scan get --id 12345
# Create a new scan
kitploit-cli scan create --target example.com --type full
# Export results to JSON
kitploit-cli scan results --id 12345 --output json
# Delete a scan
kitploit-cli scan delete --id 12345
The CLI reads configuration from the following sources (in order of precedence):
~/.kitploit/config.yaml)Create a configuration file at ~/.kitploit/config.yaml:
server: http://localhost:8080
token: your-api-token-here
output: json
timeout: 60
verbose: false
All API requests require a valid token in the Authorization header:
Authorization: Bearer <your-token>
GET /api/v1/scansReturns a list of all scans.
Query Parameters:
Response:
{
"data": [
{
"id": 12345,
"name": "Example Scan",
"target": "example.com",
"status": "completed",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:45:00Z"
}
],
"meta": {
"page": 1,
"limit": 20,
"total": 1
}
}
GET /api/v1/scans/{id}Returns details of a specific scan.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | integer | Scan ID |
Response:
{
"id": 12345,
"name": "Example Scan",
"target": "example.com",
"status": "completed",
"results": {
"vulnerabilities": 3,
"warnings": 12,
"info": 45
},
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:45:00Z"
}
POST /api/v1/scansCreates a new scan.
Request Body:
{
"name": "New Scan",
"target": "example.com",
"type": "full",
"options": {
"depth": 3,
"timeout": 300
}
}
Response:
{
"id": 12346,
"name": "New Scan",
"target": "example.com",
"status": "pending",
"created_at": "2024-01-15T11:00:00Z"
}
DELETE /api/v1/scans/{id}Deletes a specific scan.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | integer | Scan ID |
Response:
{
"message": "Scan deleted successfully",
"id": 12345
}
API requests are limited to 100 requests per minute per token. Rate limit headers are included in every response:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1705312800
``````sh
HALO_AUTHORITY_FILE=./authority.json halo hook
स्नैपशॉट को action records के समान hash chain में सील किया जाता है। एक अच्छा default यह है कि शुरुआत में एक session-level snapshot लिया जाए, और जब rules, Skills, hooks, MCP tool registries, या compaction policy बदलें तो एक नया snapshot लिया जाए। लंबे sessions को हल्का रखने के लिए, समान authority.snapshot_id वाले लगातार records को पहले पूर्ण snapshot के बाद compact कर दिया जाता है: बाद के records केवल {"snapshot_id": "...", "same_as_previous": true} रखते हैं। Pointer hash-chained रहता है, लेकिन भारी refs/omissions/stale-if block हर action पर दोहराया नहीं जाता। (Compaction प्रति recorder process होती है: hook-style capture जो प्रति tool call एक process spawn करता है, वह पूरा body तब फिर से store करता है जब पिछला पूर्ण snapshot tail record न हो, इसलिए अल्पकालिक processes chain size के बदले reuse guard चुनते हैं।)
SDK उपयोगकर्ता वही block सीधे attach करते हैं — build(..., authority={...}) या record_call(..., authority={...}); hash-only capture भी वही surface है (इनमें से किसी पर भी summaries=False):```python
from halo_record import Recorder, record_call
rec = Recorder("audit.jsonl") with record_call(rec, "crm.lookup", {"account": "acct-9"}, authority={"snapshot_id": "auth_1", "rules_hash": "sha256:..."}, summaries=False) as call: # hash-only: no summaries, no excerpts call.result = crm.lookup("acct-9")
फिर, सामान्य:```
halo verify ~/.halo/audit.jsonl
halo report ~/.halo/audit.jsonl -o report.html
कोई भी agent runtime जो post-action hook उजागर करता है, वही command feed कर सकता है — hook stdin पर एक event को JSON के रूप में पढ़ता है और एक record append करता है।
एक chain, एक बार में एक writer। एक chain एक linked list है: दो writers जो एक ही head पढ़ते हैं और दोनों append करते हैं, वह उसे fork कर देंगे (दो records जो एक ही predecessor का दावा करते हैं), और verification प्रभावित records का नाम लेगी। Recorder अपने स्वयं के appends को एक sidecar lock के साथ serialize करता है (यहाँ POSIX flock; TypeScript package में एक lock directory), और halo hook Recorder के माध्यम से append करता है, इसलिए ऊपर दिया गया hook setup कवर है। जो कुछ भी chain file को सीधे लिखता है — एक hand-rolled hook, parallel workers, एक log shipper — उसे read-head-then-append sequence के दौरान एक समकक्ष exclusive lock रखना चाहिए, या per-process chains पर लिखना चाहिए। LIMITS.md section 9 इसे पूरी तरह कवर करता है, जिसमें cross-language boundary भी शामिल है।
दो integration styles जानबूझकर विपरीत दिशाओं में विफल होते हैं — वह चुनें जिसकी विफलता आप सहन कर सकें:
handler.lost_records), लेकिन chain में कुछ भी ऐसा record नहीं दिखा सकता जो कभी लिखा ही नहीं गया — एक stalled chain फिर भी verify होती है। एक नियमित अंतराल पर witness checkpoints ही वह चीज़ हैं जो एक stalled chain को दृश्यमान बनाते हैं: एक अपेक्षित checkpoint जो कभी नहीं आता, वही alarm है।trace() wrapper fail closed करता है। यदि record लिखा नहीं जा सकता, तो exception agent की action में propagate हो जाता है — कोई evidence नहीं, कोई action नहीं। अधिक सख्त, और यह आपके agent को बाधित कर सकता है।दोनों में से कोई भी default सबके लिए सही नहीं है; जानें कि आप कौन सा चला रहे हैं।
इस बारे में सटीक रहें कि प्रत्येक layer क्या सिद्ध करती है — क्योंकि ये अलग-अलग दावे हैं, और यही अंतर मायने रखता है:
एक self-held chain एक स्थापित head के सापेक्ष integrity सिद्ध करती है: यदि किसी के पास पहले से एक chain head है, तो उसके पीछे के records में कोई भी edit, reordering, या deletion पता लगने योग्य हो जाता है। अपने आप में — इससे पहले कि operator के बाहर किसी ने कोई head देखा हो — एक chain आंतरिक consistency सिद्ध करती है, history नहीं: एक operator एक record हटा सकता है और re-seal कर सकता है, और नई file verify हो जाएगी। chain ऐतिहासिक रूप से committed उस क्षण हो जाती है जब उसका head operator के नियंत्रण से बाहर चला जाता है।
वही witness है: operator के बाहर का एक पक्ष जो chain के आवधिक checkpoints रखता है — subject id, एक record count, और दो chain fingerprints (head और chain root); सटीक payload, और कुछ नहीं। Checkpoints committed history को फिर से लिखे जाने को पता लगाने योग्य बनाते हैं, और एक छूटा हुआ checkpoint स्वयं एक दृश्यमान घटना है:``` halo anchor audit.jsonl witness.jsonl # anchor a checkpoint to a local witness halo anchor audit.jsonl witness.jsonl --check # completeness verdict against it
*time* के लिए विशेष रूप से, एक बाहरी RFC 3161 टाइमस्टैम्प चेकपॉइंट की स्व-घोषित घड़ी को एक Timestamp Authority से प्राप्त प्रमाण से बदल देता है जिसे ऑपरेटर नियंत्रित नहीं करता — "यह चेन इस हेड तक T से पहले पहुँच गई", जिसे बिना किसी होस्टेड इंफ्रास्ट्रक्चर के तीसरे पक्ष द्वारा सत्यापित किया जा सकता है। डिफ़ॉल्ट TSA मुफ़्त freetsa.org है (मूल्यांकन के लिए उपयुक्त); प्रोडक्शन के लिए `--tsa` के साथ किसी व्यावसायिक TSA (DigiCert / Sectigo / अपना स्वयं का) की ओर इंगित करें:```
halo anchor audit.jsonl witness.jsonl --timestamp # attach a TSA time proof to the checkpoint
halo anchor audit.jsonl witness.jsonl --check # reads the token's claimed time
--check पुष्टि करता है कि टोकन इस चेन स्थिति को बाइंड करता है और इसका प्रमाणित समय पढ़ता है, लेकिन यह TSA के हस्ताक्षर को सत्यापित नहीं करता — यह जानबूझकर एक मानक टूल पर छोड़ दिया गया है ताकि समीक्षक हमारे किसी भी कोड पर भरोसा न करे। समय को स्वतंत्र रूप से सत्यापित करने के लिए (यही वह चीज़ है जो आप एक सुरक्षा समीक्षक को सौंपते हैं):```
python3 -c 'import json,base64; cps=[json.loads(l) for l in open("witness.jsonl") if l.strip()]; t=[c["tsa"] for c in cps if c.get("tsa")][-1]; open("token.tsr","wb").write(base64.b64decode(t["token_b64"])); print(t["digest"])' curl -s -o tsa-ca.pem https://freetsa.org/files/cacert.pem # CA for the default TSA (a commercial TSA publishes its own) openssl ts -verify -digest -in token.tsr -CAfile tsa-ca.pem # → "Verification: OK"
एक और सीमा, स्पष्ट रूप से कही गई: न तो श्रृंखला और न ही साक्षी यह साबित करते हैं कि हर वास्तविक दुनिया की कार्रवाई रिकॉर्डर से होकर गुज़री। यह **कैप्चर पूर्णता** है — यह इस बात का गुण है कि रिकॉर्डर स्टैक में कहाँ बैठता है (नेटिव इंस्ट्रुमेंटेशन, हुक्स, गेटवे अंतर्ग्रहण), किसी हैश का नहीं। रिकॉर्ड्स में एक `source` टैग ठीक इसी कारण से होता है। इस पृष्ठ के शीर्ष पर "स्वयं जाँचें" के अंतर्गत दावों की तालिका इन तीन परतों का सारांश है।
कोई भी साक्षी चला सकता है। आपके द्वारा स्वयं चलाया गया साक्षी इतिहास को *आपके* प्रति प्रतिबद्ध करता है; इसे *आपके ग्राहक* के प्रति प्रतिबद्ध करने के लिए एक ऐसे साक्षी की आवश्यकता होती है जिस पर उनके भरोसे का कारण हो। प्रोटोकॉल किसी भी स्थिति में खुला है।
एक होस्टेड, मान्यता प्राप्त साक्षी ही वह तरीका है जिससे यह परियोजना स्वयं को बनाए रखेगी। प्रारंभिक पहुँच: [email protected]।
## श्रृंखला में व्यक्तिगत डेटा
श्रृंखला केवल-जोड़ने वाली (append-only) है: किसी रिकॉर्ड में सील की गई कोई भी चीज़ वहीं रहती है, क्योंकि
इसे हटाने से उसके बाद की हर चीज़ के सत्यापन में बाधा आएगी। टूल आर्गुमेंट्स पहले से ही
संभाले जाते हैं — एक हैश के साथ-साथ 200 अक्षरों तक सीमित एक संपादित (redacted) सारांश के रूप में संग्रहीत
(केवल-हैश मोड में कोई सारांश नहीं रखा जाता)।
उस वाक्य में सीमा पर ध्यान दें: *संपादित*, हटाया नहीं गया। [LIMITS.md](https://github.com/bkuan001/halo-record/blob/main/LIMITS.md)
का अनुभाग 6 स्पष्ट है कि किसी नाम या डाक पते का कोई विश्वसनीय पैटर्न नहीं होता, इसलिए
न तो उनका पता लगाया जाता है और न ही उन्हें छिपाया जाता है। और `subject` ही एकमात्र फ़ील्ड नहीं है जिसमें
आपके द्वारा दिया गया टेक्स्ट होता है — `principal`, `approver`, `session_id`, `agent`,
`authority`, `data` और सभी सारांश भी ऐसा करते हैं।
जो पैटर्न काम करता है: श्रृंखला में एक स्थिर छद्मनाम आईडी रखें और किसी भी व्यक्ति से उसका मैपिंग ऐसे सिस्टम में रखें जिससे आप हटा सकें। तब एक विलोपन अनुरोध मैपिंग को हटाकर पूरा किया जाता है। `subject` को किसी व्यक्ति की ओर नहीं, बल्कि टेनेंट संगठन की ओर इंगित रखें:```python
from halo_record import build
build("tool_call", "privacy", subject={"id": "acme", "name": "Acme Corp"})
कोई सेटिंग इसे लागू नहीं करती — यह एक अनुशासन है कि आप रिकॉर्डर को कैसे कॉल करते हैं। यह मिटाने को सुगम बनाता है; यह अनामीकरण नहीं है, और अभी तक कोई अंतर्निहित प्रतिधारण या प्रूनिंग नहीं है। LIMITS.md section 13 में पूरी फ़ील्ड सूची है, यह बताता है कि संग्रहीत इनपुट फ़िंगरप्रिंट मैपिंग हटने के बाद भी अनुमानित मान की पुष्टि क्यों कर सकता है, और उन प्रश्नों के साथ समाप्त होता है जो एक समीक्षक को पूछने चाहिए।
एक मॉडल कॉल रिकॉर्ड करें (खरीदार का पहला प्रश्न: "मेरा डेटा किस मॉडल ने देखा?"):```python from halo_record import record_model_call
record_model_call(rec, provider="anthropic", model="claude-sonnet-4-6", zdr=True, purpose="draft support reply", subject="acme") # tool=model.generate, scope=model:anthropic
## अनुपालन स्टैक में यह कहाँ बैठता है
halo-record एक साक्ष्य परत है, प्रमाणन नहीं। यह वह आर्टिफैक्ट तैयार करता है जिसे मूल्यांकन ढाँचे अलग-अलग शब्दों में बार-बार माँगते रहते हैं। एक स्कोप नोट जो नीचे दिए गए हर बुलेट पर लागू होता है: ये रिकॉर्ड के बारे में अखंडता के दावे हैं; ऑपरेटर के सापेक्ष पूर्णता के लिए एक बाहरी साक्षी की आवश्यकता होती है जो चेकपॉइंट रखता हो ([LIMITS.md §1](https://github.com/bkuan001/halo-record/blob/main/LIMITS.md))।
- **सुरक्षा प्रश्नावली और SOC 2 समीक्षाएँ:** AI अनुभागों का उत्तर स्क्रीनशॉट और गद्य के बजाय एक सत्यापन-योग्य Runtime Report से दें।
- **AIUC-1:** छेड़छाड़-स्पष्ट लॉगिंग साक्ष्य (E015.4) और प्राधिकरण घटनाओं के साथ निष्पादन-श्रृंखला रिकॉर्ड (E015.2 — एक घोषित अंतराल के साथ: तर्क-चिह्न कैप्चर नहीं किए जाते) उत्पन्न करता है, जिन्हें मानक का Accountability नियंत्रण E015 नाम देता है। E015 स्वयं अनिवार्य है; E015.2 और E015.4 इसके पूरक स्तर हैं: पास होने के लिए आवश्यक नहीं, वह जो कोई विक्रेता तब अपनाता है जब कोई ग्राहक या नियामक इसकी माँग करता है। एक बार जब श्रृंखला किसी ऐसे साक्षी पर एंकर हो जाती है जिस पर भरोसा करने का विश्वास करने वाले पक्ष के पास कारण हो — ऐसा साक्षी जिसे ऑपरेटर स्वयं चलाता है, यह प्रदान नहीं करता — तो वह एक निरंतर साक्षी-युक्त श्रृंखला बन जाती है, न कि ऑडिट के समय पुनर्निर्मित की गई श्रृंखला (श्रृंखला में क्या प्रवेश करता है, यह अभी भी कैप्चर सतह से सीमित है)। नियंत्रण-दर-नियंत्रण साक्ष्य मैपिंग, जिसमें जो जानबूझकर दायरे से बाहर है वह भी शामिल है, [`AIUC.md`](https://github.com/bkuan001/halo-record/blob/main/AIUC.md) में है।
- **OWASP Top 10 for Agentic Applications 2026:** दस में से आठ खतरे रिकॉर्ड पर नियतात्मक नीति नियमों से मैप होते हैं, दो को कारणों के साथ दायरे से बाहर चिह्नित किया गया है, और पैक रन करने योग्य रूप में आता है। एक अनुमानित सामुदायिक मैपिंग, आधिकारिक OWASP आर्टिफैक्ट नहीं। देखें [`OWASP.md`](https://github.com/bkuan001/halo-record/blob/main/OWASP.md)।
- **AARM (CSA):** छेड़छाड़-स्पष्ट एक्शन रसीद उत्पन्न करता है जिसे AARM निर्दिष्ट करता है — R5, और R6 का सीलिंग आधा (पहचान हैश में सील की जाती है, क्रिप्टोग्राफिक रूप से प्रमाणित नहीं)। halo-record रसीद परत है; पूर्ण AARM सिस्टम के लिए इसे एक प्रवर्तन गेटवे के साथ जोड़ें। देखें [`AARM.md`](https://github.com/bkuan001/halo-record/blob/main/AARM.md)।
- **Agentic Trust Controls:** ATC के साक्ष्य नियंत्रणों के पीछे के रनटाइम रिकॉर्ड — छेड़छाड़-स्पष्ट एक्शन लॉगिंग (RBM-03) और प्राधिकरण सत्यापन का रिकॉर्ड आधा (AID-05; प्रवर्तन आधा गेट का है) एक ही श्रृंखलाबद्ध रिकॉर्ड में। देखें [`ATC.md`](https://github.com/bkuan001/halo-record/blob/main/ATC.md)।
- **CSA AI Controls Matrix (AICM) / STAR for AI:** LOG-डोमेन साक्ष्य — ऑडिट रिकॉर्ड उत्पन्न, अनिर्धारित संशोधन के विरुद्ध सील किए गए, इनपुट और आउटपुट घटनाएँ लॉग की गईं — [`AICM.md`](https://github.com/bkuan001/halo-record/blob/main/AICM.md) में नियंत्रण-दर-नियंत्रण मैप किए गए। CSA का स्वयं का v1.1 क्रॉसवॉक उस डोमेन को AIUC-1 E015 से जोड़ता है।
- **MITRE ATLAS:** एजेंट-टेलीमेट्री शमन (AML.M0024) एक अखंडता गुण के साथ लागू किया गया जिसकी माँग ATLAS स्वयं नहीं करता — लॉग ऑपरेटर के बाहर किसी व्यक्ति द्वारा सत्यापन-योग्य है। देखें [`ATLAS.md`](https://github.com/bkuan001/halo-record/blob/main/ATLAS.md)।
- **EU AI Act / ISO 42001 / NIST AI RMF:** इन ढाँचों द्वारा वर्णित रिकॉर्ड-कीपिंग और लॉगिंग दायित्व एक ही आर्टिफैक्ट श्रेणी के हैं — [EU-AI-ACT.md](https://github.com/bkuan001/halo-record/blob/main/EU-AI-ACT.md), [ISO42001.md](https://github.com/bkuan001/halo-record/blob/main/ISO42001.md), और [NIST-AI-RMF.md](https://github.com/bkuan001/halo-record/blob/main/NIST-AI-RMF.md) में रूढ़िवादी रूप से मैप किए गए।
इनमें से कोई भी चीज़ अपने आप कुछ भी प्रमाणित नहीं करती। यह आपके मूल्यांकनकर्ता को देखने के लिए कुछ सत्यापन-योग्य देता है। सीमाएँ — halo-record जानबूझकर क्या नहीं करता, और जब कोई समीक्षक पूछे तो क्या कहें — [`LIMITS.md`](https://github.com/bkuan001/halo-record/blob/main/LIMITS.md) में प्रलेखित हैं।
### साक्ष्य को अपने GRC प्लेटफ़ॉर्म में लाना
अधिकांश GRC प्लेटफ़ॉर्म (Vanta, Drata, और समान) किसी नियंत्रण के विरुद्ध कस्टम साक्ष्य के रूप में अपलोड की गई फ़ाइलें स्वीकार करते हैं। halo-record का एक्सपोर्ट उस प्रवाह में सीधे डालने के लिए बनाया गया है:```bash
halo export audit.jsonl --from 2026-06-01 --to 2026-06-30 -o evidence.csv
# scope the export to the actions a control covers
halo export audit.jsonl --from 2026-06-01 --to 2026-06-30 --tool email.send --tool db.query -o evidence.csv
यह ऑडिट विंडो के लिए दो फ़ाइलें लिखता है: CSV (प्रत्येक रिकॉर्ड किए गए क्रिया के लिए एक पंक्ति, बाएँ से दाएँ समूहीकृत कब → क्या हुआ → कौन → किस अधिकार के अंतर्गत → क्या फ़्लैग किया गया → provenance → कैसे सत्यापित करें, जिसमें कॉल और उसके परिणाम का संपादित सरल-भाषा सारांश, प्रत्येक को उत्पन्न करने वाला एजेंट बिल्ड और मॉडल, जिस पहचान की ओर से यह चला, जिस रिकॉर्ड के कारण यह हुआ, उसका प्राधिकरण निर्णय और दायरा, और कोई भी व्यक्तिगत-डेटा श्रेणियाँ या अंतर्ग्रहित खतरा फ़्लैग शामिल हैं) और एक मैनिफ़ेस्ट (evidence.csv.manifest.json) जो CSV को उसके स्रोत से जोड़ता है — चेन का हेड हैश इसे उस सत्यापन-योग्य लॉग से जोड़ता है जिससे यह आया, और csv_sha256 निर्यातित फ़ाइल का स्वयं का हैश है, इसलिए निर्यात के बाद संपादित CSV अब अपने मैनिफ़ेस्ट से मेल नहीं खाता। जनसंख्या को --tool से संकीर्ण करें जब कोई नियंत्रण केवल कुछ क्रियाओं को कवर करता हो; मैनिफ़ेस्ट फ़िल्टर रिकॉर्ड करता है, इसलिए एक स्कोप्ड निर्यात यह प्रकट करता है कि यह एक उपसमुच्चय है बजाय पूरी जनसंख्या के रूप में पढ़े जाने के। दोनों को अपने लॉगिंग या मॉनिटरिंग नियंत्रण के विरुद्ध अपलोड करें; Runtime Report HTML संलग्न करें जब कोई समीक्षक स्वयं चेन सत्यापित करना चाहे। निर्यात उस चेन पर चलने से इनकार करता है जो सत्यापन में विफल होती है।
एक नेटिव पुश एकीकरण — आपके प्लेटफ़ॉर्म में स्वचालित रूप से पहुँचने वाला साक्ष्य — रोडमैप पर है। ऊपर दिया गया फ़ाइल पथ आज किसी भी ऐसे प्लेटफ़ॉर्म के साथ काम करता है जो अपलोड किए गए साक्ष्य स्वीकार करता है।
halo verify validate schema + hash chain (exit 1 broken, 3 empty chain; CI-friendly) halo report render a chain as a self-verifying HTML Runtime Report (--from/--to: a date-windowed report covering only the review period) halo policy corroborate a chain against a declarative policy pack (per-rule pass / violation / evidence-gap; exit 1 violated, 3 nothing in scope) halo serve serve per-tenant reports over HTTP, access-scoped per customer halo grant designate a report recipient (email or domain) halo viewers list who has unlocked a gated report halo anchor witness a chain head, or --check completeness (exit 1 incomplete, 3 unwitnessed) halo witness-serve run a witness over HTTP: vendors anchor chain heads, viewers fetch checkpoints halo demo scaffold the full vendor demo (record -> witness -> gated report) halo export date-bounded evidence export: CSV + manifest tied to the chain head halo sample emit a valid example log halo hash canonical sha256 of a JSON value halo hook Claude Code PostToolUse hook
## इंटीग्रिटी मॉडल
किसी रिकॉर्ड का हैश निकालने के लिए: रिकॉर्ड को लें, उसमें से `integrity.hash` हटा दें, और `integrity.prev_hash` को पिछले रिकॉर्ड के हैश पर सेट कर दें; RFC 8785 (JSON Canonicalization Scheme) के साथ कैनोनिकलाइज़ करें; बाइट्स का SHA-256 निकालें। पहले रिकॉर्ड का `prev_hash` 64 शून्य होता है। सत्यापन हर हैश को दोबारा निकालता है और हर लिंक की जाँच करता है। किसी गुप्त कुंजी की आवश्यकता नहीं है; यही तो बात है।
सोचते हैं कि सत्यापनकर्ता को भनक लगाए बिना किसी चेन से छेड़छाड़ कर सकते हैं? [प्रयास और परिणाम यहाँ हैं](https://github.com/bkuan001/halo-record/discussions/2)।
पूर्ण फ़ील्ड संदर्भ: [`halo-record.schema.json`](https://github.com/bkuan001/halo-record/blob/main/src/halo_record/halo-record.schema.json)।
## TypeScript
वही रिकॉर्डर Node के लिए भी उपलब्ध है: [`halo-record-ts`](https://github.com/bkuan001/halo-record-ts)। वही चेन प्रारूप, वही witness प्रोटोकॉल। किसी भी भाषा में लिखे गए रिकॉर्ड किसी भी सत्यापनकर्ता से सत्यापित हो जाते हैं।
## समुदाय के उदाहरण
[trail-halo-poc](https://github.com/AmeyParle/trail-halo-poc) — समुदाय का प्रूफ़ ऑफ़ कॉन्सेप्ट जो Halo रिकॉर्ड के principal authority को TRAIL क्रेडेंशियल्स से बाँधता है: एक पारस्परिक org–agent बाइंडिंग और org-हस्ताक्षरित scope grants जो Halo चेन में दर्ज किए जाते हैं, साथ में एक adversarial verification suite।
## योगदान
Issues, discussions, और pull requests का स्वागत है — बुनियादी नियमों के लिए [CONTRIBUTING.md](https://github.com/bkuan001/halo-record/blob/main/CONTRIBUTING.md) देखें (संक्षेप में: टेस्ट आवश्यक, छोटे PRs, schema परिवर्तनों पर पहले चर्चा होती है)।
## लाइसेंस
Apache-2.0
| दावा | स्व-धारित चेन | + बाहरी चेकपॉइंट्स | + विश्वसनीय कैप्चर |
|---|
| एक स्थापित आर्टिफैक्ट में संपादन का पता लगाएं | ✔ | ✔ | ✔ |
| कमिटेड इतिहास के पुनर्लेखन का पता लगाएं | — | ✔ | ✔ |
| गुम/देर से आए चेकपॉइंट्स का पता लगाएं | — | ✔ (सहमत कैडेंस) | ✔ |
| साबित करें कि हर क्रिया रिकॉर्ड की गई थी | — | — | कैप्चर सीमा पर निर्भर |
| Variable | Description | Default |
|---|
KITPLOIT_SERVER | Server URL | http://localhost:8080 |
KITPLOIT_TOKEN | API token | (none) |
KITPLOIT_OUTPUT | Default output format | table |
KITPLOIT_TIMEOUT | Request timeout in seconds | 30 |
KITPLOIT_VERBOSE | Enable verbose mode | false |
| Parameter | Type | Description |
|---|
page | integer | Page number (default: 1) |
limit | integer | Items per page (default: 20, max: 100) |
status | string | Filter by status: pending, running, completed, failed |
sort | string | Sort field: created_at, updated_at, name |
order | string | Sort order: asc, desc (default: desc) |
| Code | Description |
|---|
400 | Bad Request - Invalid parameters |
401 | Unauthorized - Invalid or missing token |
403 | Forbidden - Insufficient permissions |
404 | Not Found - Resource does not exist |
429 | Too Many Requests - Rate limit exceeded |
500 | Internal Server Error - Server error |