Construction versus call policy
Create an instance with detector selection before wrapping calls. Node createAgindow(options) loads asynchronously; await sdk.ready. Python Agindow(selection=..., **options) loads during construction; check sdk.ready and sdk.load_error. Engine loading faults preserve calls through bypass. Neither readiness check proves that a detector was selected. selection, work, selective repair rules and Node audit are construction options, not configure updates.
Shared call settings
Node uses camelCase; Python keyword settings use snake_case. Defaults below apply before configuration sources and per-call overrides. configure changes future calls; an executing call keeps its snapshot.
| Node / Python | Type and default | Behavior |
|---|---|---|
| mode / mode | observe | repair | strict; observe | Controls handling of findings, not detector selection. |
| failClosed / fail_closed | boolean; true | Opt-out affects unknown writes in repair mode. Semantic writes stay protected; strict ignores the opt-out. |
| allowedTools / allowed_tools | string array / tuple or "*"; "*" | Select tools eligible for inspection. |
| denyTools / deny_tools | string array / tuple; empty | Excludes tools from inspection. |
| buffer / buffer | integer 0–100000; 100 | Maximum recent event metadata retained locally; 0 disables retention. |
| onEvent / on_event | callback; absent | Receives events. Listener errors are contained. |
| apiKey / api_key; endpoint / endpoint | optional strings; absent | Do not switch an embedded guard to HTTP. Use explicit remote helpers for HTTP transport. |
StatisticalSelection
Node exports the StatisticalSelection type. Python accepts the equivalent JSON-compatible dict[str, object] as selection. Required scope strings identify the dataset; they do not provide authentication or vendor credentials.
| Field | Type / presence | Meaning |
|---|---|---|
| tenant, connection, vendor, operation, segment | strings; required | Scope the comparison. operation matches the guarded tool name. |
| fields | array; required | Explicit field comparisons. No inferred selection. |
| fields[].side | request | response; required | Which inspection phase owns the field. |
| fields[].path | string; required | Selected JSON Pointer, for example /value. |
| fields[].baseline; fields[].live | arrays of strings; required | Complete raw JSON documents from comparable independent calls. |
| fields[].enumeration | boolean; required | Whether enumeration comparison is enabled for that field. |
| materiality | optional number in (0, 1] | Explicit materiality floor; not repair authority. |
| work | construction integer u32; 200000000 | Guest work allowance, not milliseconds. Exhaustion does not authorize a finding or repair. |
Enable selective repair
Selective repair is off by default. Node accepts selectiveRepair: { rules, verify }; Python accepts selective_repair=SelectiveRepair(rules=(RenameRule(...),), verify=verify). Supply reviewed migration facts and a local synchronous verifier over immutable before/after JSON strings. Begin in observe, then configure mode repair or strict after evaluation. The runnable example below uses local business fixtures to verify integration; replace its authoritative snapshot and callable with your reviewed application data and existing client. It makes no vendor call and does not prove persisted writes.
Repair rule reference
Node RenameRule uses tool, side, from, to, migration and confidence. Python RenameRule uses tool, side, source, target, migration and confidence. Keys are simple top-level object names of up to 64 ASCII letters, digits or underscores, starting with a letter or underscore. One rule per tool/side, at most 16 rules. Tool and migration IDs contain 1–256 characters. The verifier receives RepairCheck with before, after and rule, returning exactly true/True to approve. It must check independent authoritative meaning or business evidence; copying values or validating a schema alone cannot establish intent. Prepare evidence outside calls; do not perform network or database I/O in the verifier.
Repair decisions and limits
Observe reports matched rules without changing payloads. Repair requires confidence at least 0.97; strict requires 0.99. Source absence preserves identity. Destination collisions, low confidence and verifier refusal leave payloads unchanged; strict halts matched unresolved drift, and repair passes unresolved shape drift through under the shared Rust policy; semantic-write blocks remain in force. Statistical findings or halts, malformed results and bypass are never cleared to permit a repair. Verifier faults, async results and unavailable capture preserve upstream behavior through bypass. Supported payloads are plain JSON objects and Node RawJson boundaries, with complete captures up to 1 MiB. Opt-in repair divides the work allowance across statistical inspection and the two preparation phases. Numeric/unit/enum rewrites, nested/array migrations and automatic discovery are outside this option. Node guest audit FIFO cannot be combined with selectiveRepair; use repair events for local observation. This does not provide a durable repair archive or persisted write proof.
Node-specific options
These fields are not Python Config keywords. Types are exported as Config, Options and GuardOptions; use type-only imports in TypeScript. Node defaults spans to true. The headers, transformers, sync, endpoint, sidecar and debug fields are accepted configuration metadata; they do not activate header injection, a transformation pipeline, polling or transport.
| Option | Type / default | Purpose |
|---|---|---|
| spans; debug | optional booleans; true / absent | OTel span emission and debug configuration. |
| headers | string record; absent | Accepted metadata; no automatic header injection. |
| transformers | record of (value: unknown) => unknown; absent | Accepted callback metadata; no automatic transformer pipeline. |
| sidecar; sync | URL string; {contracts?: number, drift?: number} | Configuration metadata; does not select remote execution or provision refresh. |
| audit | {tenant: string, capacity?: number, maxBytes?: number}; absent | Opt-in guest FIFO. Default capacity 64 (1–256); maxBytes 524288 (1024–1048576). Audit tenant must match selection tenant. |
Guard options and operation identity
guard(fn, options) and Python guard(fn, **options) accept tool and operation plus call-policy settings. operation is read, write or unknown; generic callables default to read. Label writes and uncertain operations explicitly. Node also supports toolName for dynamic names and inputShape raw or parsed. A function returning a Promise stays asynchronous; Python coroutine functions stay asynchronous. Unsupported adapter shapes need an explicit supported callable boundary.
Precedence and updates
At Node construction: explicit values > environment > nearest JSON .agindowrc > defaults. Python keyword overrides follow the same order; an explicitly supplied Config object replaces the resolved configuration as a whole. Node guard options override initial policy; later configure revisions can supersede options on existing guards for future calls. Python guard keyword changes override its instance/context snapshot. Python context changes apply only to this instance in the current task. Do not assume these update rules are identical.
Environment and JSON files
Both hosts read AGINDOW_MODE, AGINDOW_KEY, AGINDOW_ENDPOINT, AGINDOW_BUFFER and AGINDOW_FAIL_CLOSED. Node also reads AGINDOW_SIDECAR, AGINDOW_SPANS and AGINDOW_DEBUG. Boolean environment values are exactly true or false. A malformed nearest .agindowrc is warned about and ignored; invalid explicit or environment policy can raise AgindowSetupError. Python files accept camelCase aliases for failClosed, apiKey, allowedTools and denyTools and convert lists to tuples. Python rejects unsupported configuration fields. Keep selection in application construction rather than assuming the JSON config loads detector windows.
import { createAgindow } from 'agindow';
import type { RepairCheck } from 'agindow';
// Load authoritative application data and reviewed migration facts outside calls.
const names = new Map([['customer-123', 'Ada']]);
function verify(check: RepairCheck): boolean {
const before = JSON.parse(check.before) as Record<string, unknown>;
const after = JSON.parse(check.after) as Record<string, unknown>;
return check.rule.migration === 'crm-name-v2-reviewed'
&& typeof after['id'] === 'string'
&& names.has(after['id'])
&& before['id'] === after['id']
&& before['contact_name'] === names.get(after['id'])
&& after['display_name'] === names.get(after['id']);
}
const sdk = createAgindow({ mode: 'observe', selectiveRepair: {
rules: [{ tool: 'crm.create', side: 'request', from: 'contact_name', to: 'display_name',
migration: 'crm-name-v2-reviewed', confidence: 1 }], verify,
} });
await sdk.ready;
// Local fixture callable; replace with your existing API client after review.
const create = sdk.guard((payload: object) => payload, { tool: 'crm.create', operation: 'write' });
const input = { id: 'customer-123', contact_name: 'Ada' };
if (create(input) !== input) throw Error('Observe changed the input');
sdk.configure({ mode: 'repair' });
const repaired = create(input) as Record<string, unknown>;
if (repaired['display_name'] !== 'Ada' || 'contact_name' in repaired) throw Error('Repair was not applied');
if (!sdk.recent().some(event => event.type === 'repair')) throw Error('Repair event missing');
console.log('Reviewed local rename verified and applied');import json
from agindow import Agindow, Config, RenameRule, RepairCheck, SelectiveRepair
# Load authoritative application data and reviewed migration facts outside calls.
names = {"customer-123": "Ada"}
def verify(check: RepairCheck) -> bool:
before = json.loads(check.before)
after = json.loads(check.after)
return bool(check.rule.migration == "crm-name-v2-reviewed"
and after.get("id") in names and before.get("id") == after.get("id")
and before.get("contact_name") == names[after["id"]]
and after.get("display_name") == names[after["id"]])
sdk = Agindow(Config(mode="observe"), selective_repair=SelectiveRepair(
rules=(RenameRule(tool="crm.create", side="request", source="contact_name", target="display_name",
migration="crm-name-v2-reviewed", confidence=1.0),), verify=verify))
assert sdk.ready, sdk.load_error
# Local fixture callable; replace with your existing API client after review.
@sdk.guard(tool="crm.create", operation="write")
def create(payload: dict[str, str]) -> dict[str, str]:
return payload
value = {"id": "customer-123", "contact_name": "Ada"}
assert create(value) is value
sdk.configure(mode="repair")
assert create(value) == {"id": "customer-123", "display_name": "Ada"}
assert any(event.type == "repair" for event in sdk.recent())
print("Reviewed local rename verified and applied")